Fork me on GitHub

Scripts côté server PHP, Silex (Symfony), Node.js

Avant les pages dynamiques

Le premiers servers web se limitaient à servir des fichiers statiques: HTML, images, etc.

CLIENT SERVER GET /index.html HTTP/1.1 HTTP/1.1 200 OK ... index.html
  • L’URL correspond à un chemin dans le système de fichiers du serveur.

Génération statique

  • Fichiers HTML sont assemblés à partir de plusieurs composants,
  • Compilés avant d’être chargés sur le serveur

Un exemple moderne

menu.html content.md footer.jade index.html Markdown Jade
  • Markdown: transformation Texte → HTML,
  • Jade syntaxe simplifiée pour HTML,
  • Perl langage de programmation générique.

Ces transparents sont générés statiquement (Markdown + Jekyll).

Web 1.0 : pages dynamiques

La création du document advient au moment de la requête

GET /app.php HTTP/1.1 HTTP/1.1 200 OK app.php Moteur de Scripting Server d'authentification Database template XML document HTML généré

Le serveur peut

  • Compiler le document à la volée (comme dans la génération statique),
  • Interagir avec d’autres serveurs (authentification, API, …),
  • Interroger des bases de données.

Web 2.0 : Applications web

Focalisées autour de l’interaction avec l’utilisateur

GET /users.json HTTP/1.1 HTTP/1.1 200 OK Application Web Server d'authentification Database template XML document JSON généré
  • Les URL ne correspondent plus à des fichiers sur le serveur,
  • Une URL indique une ressource virtuelle, une action,
  • Exécution de l’application web
    • par un serveur web (e.g. Apache+PHP, Tomcat+Java, …),
    • ou par son propre serveur (e.g. Node.js, …).

Frameworks Web

Un framework web est une bibliothèque et une collection d’outils qui facilitent la construction d’applications web.

Quelques composants classiques d’un framework

  • API HTTP(S) : parsing/écriture de requêtes/réponses HTTP,
  • Router : définit la correspondance URL → Code à exécuter,
  • Moteur de templates: génération Modèles → Pages HTML,
  • Stockage volatile: persistance, sessions, memcache,
  • Abstraction de bases de données,
  • Mechanismes de sécurité: injections, XSS, CSRF,
  • Caching, Internationalisation, …

Exemples: Symfony (PHP), Silex (PHP, basé sur Symfony), Zend (PHP), Node.js (JavaScript), Ruby on Rails (Ruby), Django (Python), Flask (Python), Java EE, …

PHP

Programmer en PHP

PHP est un langage interprété, dynamiquement typé, impératif et orienté aux objets avec une syntaxe inspirée par Perl, C et d’autres languages similaires.

<?php
    echo "Hello World!";
?>

PHP est aussi un framework web (assez basique):

  • API HTTP(S),
  • Moteur de templates (PHP est un langage de templating),
  • Sessions,
  • Abstraction de bases de données (SQL).

Délimiteurs PHP

PHP est orienté au texte :

  • Seul le code entre les délimiteurs <?php et ?> est exécuté.
  • Tout autre texte est affiché verbatim.
<?php
    echo "Hello World!\n";
?>
Hello Again!

Sortie

Hello World!
Hello Again!

Nous NE NOUS SERVIRONS PAS de cela !

Commentaires

Les commentaires s’écrivent comme en C

<?php
    echo "Hello "; // Un commentaire
    /*
       Un commentaire
	   sur plusieurs lignes
    */
?>

Ou comme en Perl

<?php
    echo "World!"; # Encore un commentaire
?>

Variables

Les noms de variables commencent toujours par dollar ($).

<?php
    $a = 10;
    echo $a;
?>

Les variables n’ont pas de type, elles ne sont pas déclarées, elles sont initialisées a une valeur par défaut.

<?php
    $foo = 10;
    echo $foo;
    $foo .= " apples";
    echo $foo;            # Affiche "10 apples"
?>

Les variables sont converties automatiquement, ou leur type peut être forcé par un cast (comme en C).

<?php
  $foo = "10";
  $foo += 2;                 # $foo vaut 12
  $bar = $foo . " apples";   # $bar vaut "12 apples"
  $fee = (boolean) $bar;     # $fee vaut TRUE
?>

Portée

Les variables ont portée locale. Les fonctions introduisent une nouvelle portée locale.

<?php
  $a = "Hello";
   
  function foo() {
      echo $a;    # Cette variable est locale à foo
  }
    
  foo();          # N'affiche rien et donne un
                  # warning en PHP5
?>

Une fonction peut déclarer explicitement ses variables global, pour les importer d’une portée externe.

<?php
    $a = "Hello";
    
    function foo() {
        global $a;
        echo $a;       # Cette variable est globale
    }
    
    foo();             # Affiche "Hello";
?>

Constantes

Les constantes ne sont pas précédées par un symbole $. Elles peuvent être définies avec la fonction define

<?php
    define("COLOR", "blue");
    echo COLOR;                # Affiche "blue"
?>

ou avec le mot clef const

<?php
    const COLOR="blue";
    echo COLOR;                # Affiche "blue"
?>

Leur portée est toujours globale

<?php
    const COLOR="blue";
    
    function foo() {
        echo COLOR;
    }
    
    foo();                # Affiche "blue"
?>

Chaînes de caractères (guillemets simples)

<?php
  echo 'Bonjour, ';
  # Il faut échapper les ' avec un backslash \
  echo 'J\'apprends "PHP". ';
  echo 'Les retours à la ligne
sont permis
   entre guillemets simples
';
  # On doit échapper les backslash avant le guillmet
  echo 'Ceci est un backslash \\';
  # Tous les autres sont pris tels quels
  echo ' ceci \ aussi. ';
  echo 'Même ceci : \n';
?>

Sortie

Bonjour, J'apprends PHP. Les retours à la ligne
sont permis
   entre guillemets simples
Ceci est un backslash \ ceci \ aussi. Même ceci : \n

Chaînes de caractères (guillemets doubles)

<?php
  # Il faut échapper les "
  echo "V'là un \"backslash\": \\
";
  echo "Ceci est un retour à la ligne : \n";
  $foo = 42;
  echo '$foo est une variable';
  # Les variables sont substituées
  echo "\nLa réponse est : $foo \n";
  # Les accolades évitent les ambiguïtés
  echo "Votre {solde} est 2*${foo}00\n";
?>

Sortie

V'là un "backslash": \
Ceci est un retour à la ligne :
$foo est une variable
La réponse est : 42 
Votre {solde} est 2*4200

Chaînes de caractères (Heredoc)

Syntaxe pour des chaînes complexes. On commence par <<<Identifier et on termine par Identifier, avec Identifier n’importe quel nom valide.

<?php
    echo <<<EOT
'A thousand kisses buys my heart from me;
And pay them at thy leisure, one by one.
What is ten hundred touches unto thee?
Are they not quickly told and quickly gone?
Say, for non-payment that the debt should double,
Is twenty hundred kisses such a trouble?

EOT;
?>

Mêmes propriétés qu’entre guillemets doubles, à l’exception de l’échappement de ".

Concaténation de chaînes

Le point (.) est l’opérateur de concaténation.

<?php
  $a = 'Hello' . " World";
  $b = "$a!";
  $c = (2 * 10) . " " . $b;
  # $c vaut "20 Hello World!"
?>

Tableau associatifs

En PHP les index des tableaux peuvent avoir tout type

<?php
    $tab[0] = "Hello";
    $tab["one"] = "World";
    $tab[true] = "!";
    echo "$tab[0] ${tab['one']} ${tab[true]}";
	# Affiche "Hello world !"
?>

Il sont construits par la fonction array et affichés avec la fonction print_r.

<?php
    $tab = array(0 => 10,
	             "nested" => array(6 => 5, 13 => 9, "a" => 42));
    print_r($tab);
?>

Sortie

Array
(
    [0] => 10
    [nested] => Array
        (
            [6] => 5
            [13] => 9
            [a] => 42
        )

)

Syntaxe impérative

<?php
    if ($a > $b) {
        echo "a is bigger than b";
    } elseif ($a == $b) {
        echo "a is equal to b";
    } else {
        echo "a is smaller than b";
    }
?>
<?php
    $i = 1;
    while ($i <= 10) {
        echo $i++;
    }
?>
<?php
    for ($i = 1; $i <= 10; $i++) {
        echo $i;
    }
?>
<?php
    $arr = array(1, 2, 3, 4);
    foreach ($arr as $value) {
        echo $value * 2;
    }
?>
<?php
    $jours = array(
        "Sunday" => "Lundi",
        "Monday" => "Mardi",
        "Tuesday" => "Mercredi"
    );
    foreach ($jours as $eng => $fr) {
        echo "$eng se traduit par $fr.\n";
    }
?>
<?php
    function foo($a, $b, $c=true) {
        if ($c)
            return $a + $b;
        else
            return $a - $b;
    }
    
    echo foo(1, 2) . " ";
    echo foo(1, 2, false);
?>
<?php
  $counter = 10;
  $incr = function($i) use ($counter) {
    $counter += $i;
    echo $counter . ' ';
  };
  
  $incr(1); $incr(2); $incr(3);
  # Affiche 11 12 13
?>
<?php
  # exécute of script1.php
  include 'script1.php';
  # comme avant, mais erreur si le fichier n'existe pas
  require 'script1.php';
  # exécute script2.php, seulement s'il ne l'a pas déjà été
  include_once 'script2.php'; 
  # comme avant, mais erreur si le fichier n'existe pas
  require_once 'script2.php';
?>

Toutes les inclusions sont textuelles : les variables globales de chaque fichier sont disponibles pour tous les autres.

Lectures

Syntaxe orientée aux objets

<?php
  class SimpleClass extends BasicClass
  {
    // Attribut d'instance
	public $var = 'a default value';
	// Attribut de classe
	public static $classvar = 'another value';
	// Méthode d'instance
	public function displayVar() {
	  echo $this->var;
	}
	// Méthode de classe
	public static function displayClass() {
	  echo parent::classvar;
	}
  }
  SimpleClass::displayClass();   # Affiche "another value"
  $x = new SimpleClass();
  $x->displayVar();               # Affiche "a default value"
?>

Espaces de noms

<?php
  # La déclaration du namespace doit aller au début du fichier
  namespace Projets\Projet1;
  class MaClasse {}
  function mafonction {}
  mafonction();
?>
<?php
  include 'projet1.php';

  $a = new Projets\Projet1\MaClasse();
  Projets\Projet1\mafonction();

  use Projets\Projet1 as P1;
  $b = new P1\MaClasse();

  use Projets\Projet1\MaClasse;
  $c = new MaClasse();
?>

API HTTP

PHP fournit quelques variables globales par défaut qui représentent la requête HTTP courante

  • $_GET paramètres de l’URL (query string),
  • $_POST, $_FILES contenu de la requête,
  • $_SERVER entêtes HTTP,
  • $_COOKIE cookies,
  • $_SESSION stockage volatile.

Nous n’allons PAS NOUS SERVIR de cela

Silex

Silex

Silex est un micro-framework web écrit en PHP. Il comporte

  • Router,
  • Stockage volatile: Sessions.

Modules optionnels

  • Moteur de templates (Twig),
  • Abstraction de bases de données (Doctrine),
  • Mechanismes de sécurité: injections, XSS, CSRF,
  • Caching, Internationalisation, Mail, …

Silex est basé sur Symfony, un framework full-stack.

Silex est très adapté aux applications single page, qui présentent une seule page web et dont le code tient en quelques fichiers.

Documentation : http://silex.sensiolabs.org/documentation

Hello world

<?php
  require_once 'vendor/autoload.php';    # Charge Silex

  $app = new Silex\Application();   # Crée l'application web

  function hello() {
	  return 'Hello World!';        # On ne fait pas de echo
  }
  $app->get('/', hello);   # Définit une action pour l'URL /

  $app->run();                     # Lance l'application web
?>

Router

Le router associe une fonction (gestionnaire) à chaque requête pour une URL.

$app->get('/url1', gest1);   # Requêtes GET

$app->post('/url2/form', gest2);  # Requêtes POST

# Avec une fonction anonyme et une URL parametrée
$app->get('/url/{param}', function ($param) {
  return 'Hello ' . $param;
});

À une requête pour /url/toto, le dernier gestionnaire répond

Hello toto

API HTTP

Un gestionnaire lit une Request est écrit une Response

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$app->get('/form', function (Request $req) {
    $nom = $req->query->get('name');
    return new Response('Hello ' . $nom, 202);
});

$app->post('/form', function (Request $req) {
    $nom = $req->request->get('name');
    return new Response('Hello ' . $nom, 202);
});

À une requête pour /form?name=toto répond (avec code 202)

Hello toto

Même chose pour les données envoyées par POST.

Node.js

Node.js

Node.js est un micro-framework web écrit en JavaScript. Son noyau ne comporte que

  • Server Web,
  • API HTTP,
  • Gestionnaire de paquets.

Il existe énormément de modules optionnels :

  • Router, Middlewares : (Connect, Express),
  • Stockage volatile : Sessions, Memcache, …
  • Moteurs de templates,
  • Abstraction de bases de données
  • Mechanismes de sécurité,
  • WebSockets, …

Docs : http://docs.nodejitsu.com/, http://nodejs.org/api/.