4. Développement Web
PHP





4.1. Introduction

Le langage PHP, pour PHP Hypertext Preprocessor, (PHP étant un acronyme récursif, voir ci-après) a été créé au début des années 1990 par Rasmus Lerdorf. Initialement PHP signifait Personal Home Page Tools.

PHP est un langage de script open source spécialement conçu pour le développement d'applications web et peut être intégré facilement au (X)HTML. Il est à la base un langage procédural mais dispose également d'une couche objet.

PHP peut être utilisé :

  • comme langage de script côté serveur
  • ou comme langage de programmation en ligne de commande

Un sigle ou acronyme récursif n'a de sens que si les lettres qui le composent (sauf la première) correspondent à un programme. Par exemple, FINE pour Fine Is Not Emacs, Fine étant un clone du logiciel EMACS, est un acronyme récursif.

Cependant, GNU n'est, à mon sens, pas un acronyme récursif contrairement à ce que l'on dit. Cela devrait être GINU = GINU Is Not Unix ou GSNU car on écrit GNU's Not Unix, mais on oublie le IS représenté par 's ce qui, selon moi, travestit le sens de l'expression.

Un exemple d'acronyme récursif pourrait être KISS = Kiss Is So Sweet ou MISS = Miss Is So Sad. L'idée étant qu'un acronyme, que l'on pourrait qualifier de parfait, ait un sens et que les lettres qui le composent donnent une définition proche du sens de l'acronyme.

On peut également s'amuser à créer des acronymes récursifs en mixant deux langues comme par exemple SHAME = Shame Honte A Moi Essentiellement.

Nous allons dans la suite de ce cours appréhender trois aspects majeurs du langage, à savoir :

4.2. Les bases du langage

Mais dans un premier temps, intéressons nous aux bases du langage.

Les caractéristiques du langage sont les suivantes :

On introduit le code PHP dans une page (X)HTML ou dans un fichier contenant uniquement du code PHP par les balises :

<?php
.... mon code PHP ...
?>

4.2.1. Les variables

Voici quelques exemples de définition de variables. Les conventions sont les mêmes qu'en C excepté le symbole dollar qui précède chaque nom de variable :

  1. $x = 1;
  2. $_x_1 = 2;
  3. $ma_chaine = "coucou";

4.2.2. Les types

On retrouve les types de base comme les booléens, les entiers, les réels, les chaînes de caractères. Pour connaître le type d'une variable, on utilise la fonction gettype() qui retourne une chaîne de caractères.

Etant donné le typage dynamique, on peut réutiliser le même nom de variable et lui affecter des valeurs différentes :

  1. $x = 1;
  2. echo "type de x = " . gettype( $x ) . "\n";
  3. $x = true;
  4. echo "type de x = " . gettype( $x ) . "\n";
  5. $y = 3.1415926;
  6. echo "type de y = " . gettype( $y ) . "\n";
  7. $z = "coucou";
  8. echo "type de z = " . gettype( $z ) . "\n";
  9.  

Le résultat obtenu est le suivant :

type de x = integer
type de x = boolean
type de y = double
type de z = string

4.2.3. Les chaînes de caractères

Les chaînes de caractères peuvent être introduites de trois manières différentes :

  1. <?php
  2. $x = 3.14;
  3.  
  4. $chaine1 = 'x = $x\n';
  5. $chaine2 = "x = $x\n";
  6.  
  7. $chaine3 = <<<'NOWDOC'
  8. !!!
  9.   x = $x\n
  10. !!!
  11. NOWDOC;  
  12.  
  13. $chaine4 = <<<HEREDOC
  14. -+-
  15.   x = $x\n
  16. -+-
  17. HEREDOC;
  18.  
  19. echo $chaine1 . "\n";
  20. echo $chaine2 . "\n";
  21. echo $chaine3 . "\n";
  22. echo $chaine4 . "\n";
  23.  
  24. ?>
  25.  
x = \$x\n
x = 3.14

!!!
  x = \$x\n
!!!
-+-
  x = 3.14
 
-+-

On notera que le mot clé echo permet l'affichage d'information sur le flux de sortie standard et que le point (.) réalise la concaténation des chaînes.

4.2.4. Les tableaux

Les tableaux en PHP sont des tableaux associatifs de la forme clé => valeur.

Si on insère que des valeurs les indices prendront des valeurs entières.

Les tableaux peuvent également prendre des valeurs de type différents.

4.2.4.a  création d'un tableau

  1. <?php
  2.  
  3. $mon_tableau_vide = array();
  4. print_r( $mon_tableau_vide );
  5.  
  6. $mon_tableau = array( 1, 2, 3 );
  7. print_r( $mon_tableau );
  8.  
  9. $mon_tableau_cles = array ( "rouge" => "#FF0000",
  10.     "vert" => "#00FF00", "violet" => "#FF00FF" );
  11. print_r( $mon_tableau_cles );  
  12.  
  13. ?>
  14.  
Array
(
)
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)
Array
(
    [rouge] => #FF0000
    [vert] => #00FF00
    [violet] => #FF00FF
)

4.2.4.b  insertion de valeurs dans un tableau

  1. <?php
  2.  
  3. $mon_tableau = array();
  4.  
  5. // ajout de valeurs en fin en utilisant array_push
  6. for ($i = 1; $i <= 5; ++$i) {
  7.     array_push( $mon_tableau, $i );
  8. }
  9.  
  10. // ajout de valeur en fin avec une autre syntaxe
  11. $mon_tableau[] = "coucou";
  12.  
  13. // ajout en début
  14. array_unshift( $mon_tableau, "premier" );
  15.  
  16. // insérer une valeur à la position 3
  17. $pos = 3;
  18. $value = 3.1415;
  19. $mon_tableau = array_merge(
  20.     array_slice( $mon_tableau, 0, $pos ),
  21.     array( $value ),
  22.     array_slice( $mon_tableau, $pos )
  23. );
  24.  
  25. // afficher un tableau
  26. print_r( $mon_tableau );
  27.  
  28. ?>
  29.  
Array
(
    [0] => premier
    [1] => 1
    [2] => 2
    [3] => 3.1415
    [4] => 3
    [5] => 4
    [6] => 5
    [7] => coucou
)

4.2.4.c  suppression de valeurs dans un tableau

  1. <?php
  2.  
  3. $mon_tableau = array( 1, 2, 3, 4, 5, 6, 7, "huit", 9 );
  4.  
  5. $value_to_remove = 7;
  6. $key = array_search( $value_to_remove, $mon_tableau );
  7. if ($key !== false) unset( $mon_tableau[ $key ] );
  8.  
  9. // afficher le tableau
  10. print_r( $mon_tableau );
  11.  
  12. ?>
  13.  
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [7] => huit
    [8] => 9
)

4.2.4.d  autres fonctions de manipulation des tableaux

Il existe de nombreuses fonctions liées à la manipulation des tableaux.

4.2.5. Expressions algébriques

On retrouve les mêmes types d'expressions qu'en langage C :

  1. <?php
  2.  
  3. $x = 3;
  4. $y = 7;
  5. echo "1 << $x = "  . (1 << $x) . "\n";
  6. echo "$x & $y = " . ($x & $y) . "\n";
  7. echo "sqrt($x) = " . sqrt( $x ) . "\n";
  8. echo "sin($x) * cos($x) = " . (sin($x) * cos($x)) . "\n";
  9. ?>
  10.  
  11.  
1 << 3 = 8
3 & 7 = 3
sqrt(3) = 1.7320508075689
sin(3) * cos(3) = -0.13970774909946

4.3. Accès aux bases de données

L'accès aux bases de données se fait au travers de la couche PDO (PHP Data Object).

La couche PDO est assez lourde à manipuler car il faut gérer les exceptions éventuelles qui seront générées en cas d'erreur. Pour simplifier les traitements, on crée généralement une classe PHP donc le constructeur réalisera la connexion à la base de données et on ajoute à cette classe, un ensemble de fonctions afin de réaliser les opérations de bases que l'on appelle le CRUD :

4.3.1. Connexion à la base de données

On crée un premier fichier database_information.php qui contient les données de connexion :

  1. <?php
  2.  
  3. // -------------------------------------
  4. // Données de connexion à une base MySQL
  5. // -------------------------------------
  6.  
  7. $database_information = [
  8.     "host" => "localhost",      // hôte
  9.     "name" => "jmdb",           // nom de la base
  10.     "user" => "jm",         // utilisateur
  11.     "pass" => "jmpasswd"        // mot de passe
  12. ];
  13. ?>
  14.  

On crée ensuite une classe DatabaseConnection dans le fichier database_connection.php dont le constructeur établit la connexion avec la base de données au travers de PDO.

  1. <?php
  2. require_once( 'database_information.php' );
  3.  
  4. /**
  5.  * Class used to create a PDO connection to a MySQL
  6.  * database and provide the basic operations :
  7.  * - insert
  8.  * - update
  9.  * - delete
  10.  * - select_fetchall
  11.  * - select_fetch
  12.  */
  13. class DatabaseConnection {
  14.  
  15.     // PHP connection to database
  16.     private $pdo;
  17.    
  18.     // boolean that tells if an error occurred
  19.     private $error;
  20.    
  21.     // error message
  22.     private $error_message;
  23.  
  24.     /**
  25.      * WHAT
  26.      *
  27.      *  Return true if an error occurred, false otherwise
  28.      *
  29.      */
  30.     public function has_error() {
  31.         return $this->error;
  32.     }
  33.    
  34.     /**
  35.      * WHAT
  36.      *
  37.      *  Return the error message or an empty string if no error
  38.      *  occurred.
  39.      */
  40.     public function get_error_message() {
  41.         return $this->error_message();
  42.     }
  43.        
  44.     /**
  45.      * WHAT
  46.      *   Check if SQL query starts with given string
  47.      *
  48.      * EXCEPTION
  49.      *   raise PDOException if it is not the case
  50.      *
  51.      */
  52.     private function check_sql_starts_with( $query, $start ) {
  53.        
  54.         $sql = trim( $query );
  55.         $beginning = strtoupper( substr( $query, 0, strlen( $start )) );
  56.         $start = strtoupper( $start );
  57.         if ($beginning != $start) {
  58.             throw new PDOException( "query should start with " . $start );
  59.         }
  60.  
  61.     }
  62.    
  63.     /**
  64.      * WHAT
  65.      *
  66.      *  Raise exception and format message in function of
  67.      *  the place it was used (CLI or web site).
  68.      *
  69.      */
  70.     private function raise( $fn_name ) {
  71.    
  72.         // gestion des erreurs éventuelles avec message
  73.         // d'erreur
  74.         $this->error = true;
  75.        
  76.         if (php_sapi_name() == "cli") {
  77.             $s = "Error: " . $pdo_exc->getMessage() . "\n";
  78.         } else {
  79.             $s = "<p class=\"error\">" . $pdo_exc->getMessage() . "</p>";
  80.         }
  81.        
  82.         if (strlen( $fn_name ) != 0) {
  83.             $s . " inside " . $fn_name;
  84.         }
  85.        
  86.         $this->error_message = $s;
  87.     }
  88.    
  89.     /**
  90.      * WHAT
  91.      *
  92.      *   Constructor that initiate the database connection with
  93.      *   PDO
  94.      *
  95.      */
  96.     public function __construct() {
  97.        
  98.         global $database_information;
  99.        
  100.         $host = $database_information[ "host" ];
  101.         $name = $database_information[ "name" ];
  102.         $user = $database_information[ "user" ];
  103.         $pass = $database_information[ "pass" ];
  104.        
  105.         $this->error = false;
  106.         $this->error_message = "";
  107.        
  108.         $db_access = "mysql:host=$host;dbname=$name;charset=UTF8";
  109.        
  110.         try {
  111.  
  112.             // création de la connexion qui sera retournée dans
  113.             // la variable $pdo
  114.             $this->pdo = new PDO( $db_access, $user, $pass );
  115.            
  116.         } catch( PDOException $pdo_exc ) {
  117.  
  118.             raise( _METHOD_ );
  119.            
  120.         }
  121.     }
  122.  
  123. }
  124.  
  125. ?>
  126.  

On gère le fait que l'on utilise la classe soit sur le site web, soit en ligne de commande (CLI = Command Line Interface) afin de mettre en forme le message d'erreur.

4.3.2. Insertion des données : INSERT

On peut ensuite insérer des données en utilisant des requêtes paramétrées. Le code ressemblera à cela :

  1. <?php
  2. require_once( 'database_connection.php' );
  3.  
  4. $db_cnx = new DatabaseConnection();
  5.  
  6. $clients = [
  7.     [ "Decafer", "Marc" ],
  8.     [ "Bon", "Jean" ],
  9.     [ "Ahauque", "Tom" ],
  10.     [ "Neymar", "Jean" ]
  11. ];
  12.  
  13. $sql = "INSERT INTO client (`cl_id`, `cl_nom`, `cl_prenom`)" .
  14.     " VALUES (NULL, :nom, :prenom);";
  15.  
  16. $fields = array( ":nom", ":prenom" );
  17.  
  18. $db_cnx->insert( $sql, $fields, $clients );
  19.  
  20. if ($db_cnx->has_error() ) {   
  21.     echo $db_cnx->get_error_message();
  22. }
  23. ?>
  24.  

On ajoute alors une méthode insert() à la classe DatabaseConnection :

  1. <?php
  2.  
  3. class DatabaseConnection {
  4.  
  5.     /**
  6.      * WHAT
  7.      * 
  8.      *  Insert data into database table
  9.      *
  10.      * PARAMETERS
  11.      *
  12.      *  - query : for example "INSERT INTO client (`cl_id`, `cl_nom`, `cl_prenom`)
  13.      *          VALUES (NULL, :nom, :prenom);"
  14.      *  - $fields : array of string, for example array( ":nom", ":prenom" )
  15.      *  - $data : array of array
  16.      *
  17.      */
  18.     public function insert( $query, $fields, $data ) {
  19.    
  20.         $this->error = false;
  21.         $this->error_message = "";
  22.        
  23.         try {
  24.  
  25.             $this->check_sql_starts_with( $query, "insert" );
  26.        
  27.             $statement = $this->pdo->prepare( $query );
  28.        
  29.             foreach( $data as $record ) {
  30.                
  31.                 if (count( $record ) != count( $fields )) {
  32.                     throw new PDOException( "bad number of parameters: " .
  33.                         count( $fields ) . " expected, but " .
  34.                         count( $record ) . " found" );
  35.                 }
  36.                
  37.                 $data_to_insert = array();
  38.                 for ($i = 0; $i < count( $fields ); ++$i) {
  39.                     $data_to_insert[ $fields[ $i ] ] = $record[ $i ];
  40.                 }
  41.                
  42.                 $statement->execute( $data_to_insert );  
  43.        
  44.             }
  45.            
  46.         } catch( PDOException $pdo_exc ) {
  47.            
  48.             raise( _METHOD_ );
  49.            
  50.         }
  51.        
  52.     }
  53.        
  54. }
  55. ?>
  56.  

4.3.3. Récupération des données : SELECT

Pour récupérer les données, deux possibilités s'offrent à nous :

4.3.3.a  Select avec fetchAll

On ajoute la fonctionnalité suivante à la classe DatabaseConnection.

  1. <?php
  2.  
  3. class DatabaseConnection {
  4.  
  5.     /**
  6.      * WHAT
  7.      *
  8.      *   Execute a select query and fetch all records found
  9.      *
  10.      * PARAMETERS
  11.      *
  12.      *  - query : a SQL query that starts with SELECT
  13.      *
  14.      * RETURN
  15.      *  
  16.      *   array of records
  17.      */
  18.     public function select_fetchall( $query ) {
  19.    
  20.         $this->error = false;
  21.         $this->error_message = "";
  22.        
  23.         $result = array();
  24.        
  25.         try {
  26.        
  27.             $this->check_sql_starts_with( $query, "select" );
  28.  
  29.             $this->pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
  30.             $statement = $this->pdo->query( $query );
  31.             // if no error fetch all
  32.             if ($statement !== false) {
  33.                 $result = $statement->fetchAll( PDO::FETCH_ASSOC );
  34.             }
  35.            
  36.         } catch( PDOException $pdo_exc ) {
  37.            
  38.             raise( _METHOD_ );
  39.                
  40.         }
  41.        
  42.         return $result;
  43.     }
  44.    
  45. }
  46. ?>
  47.  

Puis, on réalise l'appel d'une requête SQL de type SELECT, puis on récupère tous les enregistrements :

  1. <?php
  2. require_once( 'database_connection.php' );
  3.  
  4. $db_cnx = new DatabaseConnection();
  5.  
  6. $sql = "SELECT * FROM client;";
  7. $result = $db_cnx->select_fetchall( $sql );
  8.  
  9. if ($db_cnx->has_error() == true) {
  10.     echo $db_cnx->get_error_message();
  11. }
  12.    
  13. foreach( $result as $client ) {
  14.     echo $client['cl_id'] . " " . $client['cl_nom'];
  15.     echo " " . $client['cl_prenom'] . "\n";
  16. }
  17.    
  18.  
  19. ?>
  20.  

4.3.3.b  Select avec fetch

On procède de la même manière avec fetch :

  1. <?php
  2.  
  3. class DatabaseConnection {
  4.  
  5.     /**
  6.      * WHAT
  7.      *
  8.      *   Execute a select query and and return PDOStatement
  9.      *
  10.      * PARAMETERS
  11.      *
  12.      *  - query : a SQL query that starts with SELECT
  13.      *
  14.      * RETURN
  15.      *  
  16.      *   PDOStatement
  17.      */
  18.     public function select_fetch( $query ) {
  19.    
  20.         $this->error = false;
  21.         $this->error_message = "";
  22.        
  23.         $result = array();
  24.        
  25.         try {
  26.        
  27.             $this->check_sql_starts_with( $query, "select" );
  28.  
  29.             $this->pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
  30.             $statement = $this->pdo->query( $query );
  31.             if ($statement !== false) {
  32.                 $result = $statement;
  33.             }
  34.            
  35.         } catch( PDOException $pdo_exc ) {
  36.            
  37.             raise( _METHOD_ );
  38.                
  39.         }
  40.        
  41.         return $result;
  42.     }
  43.  
  44.  
  45. }
  46. ?>
  47.  
  1. <?php
  2. require_once( 'database_connection.php' );
  3.  
  4. $db_cnx = new DatabaseConnection();
  5.    
  6. // exécution de la requête SQL   
  7. $sql = "SELECT * FROM client;";
  8. $result = $db_cnx->select_fetch( $sql );
  9.    
  10. if (! $db_cnx->has_error() ) {
  11.    
  12.     // récupération des clients un à un
  13.     while ( ($client = $result->fetch( PDO::FETCH_ASSOC )) !== false ) {
  14.  
  15.         echo $client['cl_id'] . " ";
  16.         echo $client['cl_nom'] . " ";
  17.         echo $client['cl_prenom'] . "\n";
  18.  
  19.     }
  20.    
  21. }
  22. ?>
  23.  

4.3.4. Modification des données : UPDATE

On peut utiliser le même type de requête paramétrée pour mettre à jour un enregistrement :

  1. <?php
  2.  
  3. class DatabaseConnection {
  4.  
  5.     /**
  6.      * WHAT
  7.      *
  8.      *   Execute an update query
  9.      *
  10.      * PARAMETERS
  11.      *
  12.      *  - query : a parameterized SQL query that starts with UPDATE like
  13.      *   "UPDATE client SET cl_nom=:nom, cl_prenom=:prenom WHERE cl_id=:id;"
  14.      *  - fields : array of string, for example array( ":nom", ":prenom",
  15.      *   ":id" )
  16.      *  - $data : array of array like [ [ "Richer", "Jean-Michel", 1 ] ];
  17.      *
  18.      */
  19.     public function update( $query, $fields, $data ) {
  20.    
  21.         $this->error = false;
  22.         $this->error_message = "";
  23.        
  24.         try {
  25.    
  26.             $this->check_sql_starts_with( $query, "update" );
  27.        
  28.             $statement = $this->pdo->prepare( $query );
  29.        
  30.             foreach( $data as $record ) {
  31.                
  32.                 if (count( $record ) != count( $fields )) {
  33.                     throw new PDOException( "bad number of parameters: " .
  34.                         count( $fields ) . " expected, " .
  35.                         count( $record ) . " found" );
  36.                 }
  37.                
  38.                 $data_to_insert = array();
  39.                 for ($i = 0; $i < count( $fields ); ++$i) {
  40.                         $data_to_insert[ $fields[ $i ] ] = $record[ $i ];
  41.                 }
  42.                    
  43.                 $statement->execute( $data_to_insert );  
  44.        
  45.             }
  46.            
  47.         } catch( PDOException $pdo_exc ) {
  48.            
  49.             raise( _METHOD_ );
  50.                
  51.         }
  52.        
  53.     }
  54.    
  55. }
  56. ?>
  57.  
  1. <?php
  2. require_once( 'database_connection.php' );
  3.  
  4. $db_cnx = new DatabaseConnection();
  5.  
  6. $clients = [
  7.     [ "Richer", "Jean-Michel", 1 ]
  8. ];
  9.  
  10. $fields = array( ":nom", ":prenom", ":id" );
  11.  
  12. $sql = "UPDATE client SET cl_nom=:nom, cl_prenom=:prenom WHERE cl_id=:id;";
  13. $db_cnx->update( $sql, $fields, $client );
  14.  
  15. if ($db_cnx->has_error() ) {   
  16.     echo $db_cnx->error_message;
  17. }
  18.  
  19. ?>
  20.  

4.3.5. Suppression des données : DELETE

  1. <?php
  2.  
  3. class DatabaseConnection {
  4.  
  5.     /**
  6.      * WHAT
  7.      *
  8.      *   Execute a delete query
  9.      *
  10.      * PARAMETERS
  11.      *
  12.      *  - query : a parameterized SQL query that starts with DELETE like
  13.      *   "DELETE FROM client WHERE cl_id=:id;";
  14.      *  - fields : array of string, for example array( ":id" );
  15.      *  - $data : array of array like [ [ 1 ], [ 2 ] ];
  16.      *
  17.      */
  18.     public function delete( $query, $fields, $data ) {
  19.    
  20.         $this->error = false;
  21.         $this->error_message = "";
  22.        
  23.         try {
  24.            
  25.             $this->check_sql_starts_with( $query, "delete" );
  26.            
  27.             $statement = $this->pdo->prepare( $query );
  28.        
  29.             foreach( $data as $record ) {
  30.                
  31.                 if (count( $record ) != count( $fields )) {
  32.                     throw new PDOException( "bad number of parameters: " .
  33.                         count( $fields ) . " expected, " .
  34.                         count( $record ) . " found" );
  35.                 }
  36.                
  37.                 $data_to_remove = array();
  38.                 for ($i = 0; $i < count( $fields ); ++$i) {
  39.                     $data_to_remove[ $fields[ $i ] ] = $record[ $i ];
  40.                 }
  41.                    
  42.                 $statement->execute( $data_to_remove );  
  43.        
  44.             }
  45.            
  46.         } catch( PDOException $pdo_exc ) {
  47.  
  48.             raise( _METHOD_ );
  49.                        
  50.         }
  51.        
  52.     }
  53.        
  54. }
  55. ?>
  56.  
  1. <?php
  2. require_once( 'database_connection.php' );
  3.  
  4. $db_cnx = new DatabaseConnection();
  5.  
  6. $clients = [
  7.     [ 1 ]
  8. ];
  9.  
  10. $fields = array( ":id" );
  11.  
  12. $sql = "DELETE FROM client WHERE cl_id=:id;";
  13. $db_cnx->delete( $sql, $fields, $clients );
  14.  
  15. if ($db_cnx->has_error() ) {   
  16.     echo $db_cnx->get_error_message();
  17. }
  18.  
  19. ?>
  20.  

4.4. Manipulation des données de formulaires

4.4.1. Vérification en amont

Par le passé, on avait l'habitude de soumettre les données du formulaire à un script PHP qui :

  1. récupérait les données
  2. les analysait
  3. et renvoyait ces mêmes données à la page contenant le formulaire en cas d'erreur (ex: date de naissance invalide, mot de passe sans au moins une lettre majuscule) afin qu'elles soient modifiées
  4. ou enregistrait les données dans une base de données et indiquait que l'ajout ou la modification avait été effectuée

Ce processus se révèle assez lourd et engendre, en cas d'erreur (étape 3), de nombreux transferts entre le client et le serveur.

Avec le développement de Javascript et d'HTML 5, on préfère aujourd'hui vérifier la validité des données du côté client (navigateur) puis les soumettre au serveur si elles sont valides.

4.4.2. Accès aux données

Lorsque l'on soumet les données d'un formulaire (X)HTML à une page PHP sur le serveur, les données sont stockées et accessibles dans des tableaux de chaînes de caractères :

Pour faciliter les traitements, la variable \$_REQUEST a été définie et elle prend en compte les valeurs de \$_POST ou \$_GET.

Ces tableaux associatifs ont pour clé le nom du champ associé, il faut pour cela avoir renseigné pour chaque champ l'attribut name dans le formulaire (X)HTML.

Voici un petit exemple avec post et le même exemple avec get.

La première étape du traitement consiste à récupérer la valeur de chaque champ du formulaire. Toutes ces valeurs sont des chaînes de caractères. Il est en général nécessaire d'éliminer les espaces en début et/ou fin de chaîne en utilisant la fonction trim().

Il peut être ensuite nécessaire de convertir certaines valeurs en entier ou flottant. Pour cela on utilise généralement les fonctions :

On peut également vérifier si une chaîne représente un nombre en utilisant is_numeric().

4.4.3. Cas des fichiers

4.4.3.a  Formulaire

Pour uploader (télécharger) un fichier dans un formulaire, il faut utiliser un champ de type input et de type file. L'attribut accept permet de spécifier les extensions des fichiers autorisés.

Le fichier ne pourra être téléchargé que par la méthode post du formulaire.

On trouvera les informations nécessaires pour uploader un fichier sur cette page.



  

<form action="ens/l1/dev_web/upload.php" method="post"
	name="upload" enctype="multipart/form-data">
<label>Fichier :</label>
<input type="hidden" name="MAX_FILE_SIZE" value="600000" />
<input type="file" id="id_fichier" name="champ_fichier" 
	accept=".png, .pdf, .doc"
	data-max-size="11132154"
/>
 
<br /><br />
<label>&nbsp;</label>
<button>Envoyer</button>
</form>

Le formulaire doit inclure dans sa définition un attribut enctype de valeur multipart/form-data.

Les formulaires HTML fournissent trois méthodes d'encodage des données (attribut enctype de la balise form) qui seront transmises :

  • application/x-www-form-urlencoded, méthode par défaut, encodage similaire à la méthode get
  • multipart/form-data, méthode plus complexe qui permet d'inclure des fichiers
  • text/plain, défini par HTML5 réservé au débogage, à ne pas utiliser de manière générale

On peut limiter la taille du fichier en ajoutant un champ caché (hidden) juste avant le champ de type file de nom MAX_FILE_SIZE (cf. code précédent).

4.4.3.b  Traitement des données

Le script PHP qui reçoit les données doit vérifier la variable globale \$_FILES qui contient le ou les fichiers dans le cas où on aura autorisé la sélection de plusieurs fichiers (ajout de l'attribut multiple sans valeur).

Voici un exemple pour lequel on a téléchargé le fichier td1.pdf qui possède une taille de 173292 octets donc bien inférieure à la taille limite de 600000 octets :

$_FILES["champ_fichier"] = Array (of type array)
	Array["name"] = td1.pdf (of type string)
	Array["type"] = application/pdf (of type string)
	Array["tmp_name"] = /tmp/phpJka1R1 (of type string)
	Array["error"] = 0 (of type integer)
	Array["size"] = 173292 (of type integer)

Le fichier est stocké de manière temporaire dans le répertoire /tmp sous le nom phpJka1R1.

Si le fichier est plus grand que la taille autorisée, il ne sera pas téléchargé : une erreur de valeur 2 est générée et le fichier possède une taille de 0, n'a pas de type et n'est pas stocké de manière temporaire :

$_FILES["champ_fichier"] = Array (of type array)
	Array["name"] = cours.pdf (of type string)
	Array["type"] = (of type string)
	Array["tmp_name"] = (of type string)
	Array["error"] = 2 (of type integer)
	Array["size"] = 0 (of type integer)

Pour récupérer le fichier, il faudra utiliser la méthode move_uploaded_file() (voir documentation) de PHP afin de le déplacer dans un répertoire adéquat :

  1. $target_path="./upload/";
  2.  
  3. $tmp_name = $_FILES[ "champ_fichier" ][ "tmp_name" ];
  4. $dest_file_name = $target_path . basename( $_FILES[ 'champ_fichier' ][ 'name' ]);
  5. if (move_uploaded_file( $tmp_name, $dest_file_name ) ) {
  6.     // ok
  7. } else {
  8.     // error
  9. }
  10.  
  11.  

Pour cela, on crée généralement dans le répertoire public_html, un sous-répertoire, par exemple upload, auquel il faut attribuer des droits qui sont ceux du serveur web (www-data).




4.5. Exercices

Exercice 4.1

Créer un programme PHP qui permet de trier un tableau d'entiers. On initialisera le tableau avec des valeurs aléatoires et on créera une fonction qui trie le tableau en utilisant un tri à bulles et qui accepte un tableau en paramètre.

Exercice 4.2

Modifiez le programme précédent en implantant le tri sous forme d'un tri rapide.

Exercice 4.3

Récupérez les données d'un formulaire contenant un champ date et afficher la date en français.