Valid XHTML     Valid CSS2    

Un petit tuteur PHP -- a small PHP tutorial

        gilles.hunault@univ-angers.fr

Table des matières

       Voulez-vous voir un tour de cartes en PHP ?

1.   Présentation de PHP 

    1.1 Versions de PHP

    1.2 Exemples de code PHP

2.   Eléments du langage de PHP 

    2.3 Commentaires, variables, affectations etc.

    2.1 Tests et Boucles

    2.2 Sous-programmes

    2.3 Objets

    2.4 Encodages

    2.5 Sessions

    2.6 Documentation

3.   Programmation classique en PHP 

    3.1 Exemple 1 : un Bonjour complet

    3.2 Exemple 2 : Table de multiplication

    3.3 Exemple 3 : Calcul de moyennes de classe

4.   Exemples spécifiques en PHP 

    4.1 Tableaux associatifs et Expressions régulières

    4.2 Nombre de fichiers dans un répertoire

    4.3 Requêtes SQL dont SQLite et MySQL

5.   Exemples plus techniques en PHP 

    5.1 Dictionnaires d'un fichier texte

    5.2 Classification hiérarchique de données bactériologiques

    5.3 Identification automatique de vecteurs d'absence-présence

    5.4 Graphiques

    5.5 Diaporamas en PHP

    5.6 Site LEADB (bioinformatique)

    5.7 Production de pdf

    5.8 Tracé de graphe mathématique

6.   En guise de conclusion sur PHP 

1. Présentation de PHP

PHP est un langage de programmation pour les serveurs Web, orienté base de données. Ce qui signifie qu'il permet de gérer des pages HTML dynamiques sur le serveur et en particulier de construire des pages Web correspondant à des résultats de requêtes sur des bases de données de type SQL. Selon ses auteurs, sa syntaxe est proche du C, de Java et de PERL. PHP se compose d'un langage de programmation classique (affectations, tests, boucles, fonctions...), de fonctions Web (y compris pour les protocoles, services et utilitaires comme LDAP, POP3, PDF, ZIP...) et de fonctions base de données (SQLite,MySQL,PostgreSQL..).

1.1 Versions de PHP

Nous décrivons ici l'utilisation de la version 7 de PHP, avec quelques compléments sur les versions plus anciennes (PHP 3, 4, 5). comme par exemple pour la programmation objets apparue avec PHP 4. Ce tuteur est largement inspiré de la documentation officielle, vous pouvez donc l'utiliser en 2020.

PHP s'exécute sur le serveur et non pas sur le client (navigateur). C'est pourquoi on ne voit que le résultat de l'exécution du programme PHP à l'aide d'un navigateur. Suivant la configuration du serveur, une erreur PHP à l'exécution affiche un message ou se contente de renvoyer une page vide. On peut écrire une page Web avec n'importe quel éditeur de textes, sous Windows ou Linux, mais la coloration syntaxique est certainement une caractéristique minimale pour qu'un éditeur de textes soit acceptable pour PHP. Donc exit Notepad et vi, et bienvenue à Notepad++, vim Microsoft Visual Code ou Geany...

Une fois le programme écrit, il faut le transférer sur le serveur, dans un répertoire particulier, souvent public_html Pour la faculté des sciences d'Angers, ce répertoire est nommé forge_html.

Si vous connaissez déjà PERL, vous pouvez profiter du tableau synoptique des instructions PERL et PHP.

PHP est disponible sous Windows, sous MacOs et sous Unix. Le site officiel est

PHP est aussi livré en standard avec le serveur Apache et l'interpréteur PHP dans des distributions "LAMP" comme EasyPHP, Wamp et Xampp.

1.2 Exemples de code PHP

Pour utiliser PHP, une fois le logiciel installé, configuré il suffit d'écrire des fichiers de type .php plutôt que .htm ou .html et le tour est joué (lire la note locale sur les serveurs angevins).

L'appel à PHP est commencé par le marqueur <?php et se termine par le marqueur ?>.

Il faut noter que dans la version 3 dès le premier appel à PHP, le serveur Web gèrait une "session" qui gardait en mémoire un certain nombre d'informations, comme par exemple les variables PHP mais ce n'est plus le cas depuis la version 4 et il faut donc faire un appel explicite à start_session()...

Le fichier suivant, nommé xmp01.php

   <html>                                                            
     <head>                                                          
        <title> (gH) : un premier exemple en PHP</title>      
     </head>                                                         
      <body>                                                         
         Bonjour, <?php echo " tout le monde " ;?>                   
      </body>                                                        
    </html>                                                          

est une page Web qui utilise le mode normal pour afficher Bonjour et qui fait appel à PHP pour afficher tout le monde.

Attention : l'imbrication des marqueurs Web classiques et ceux de PHP n'a pas besoin d'être équilibrée tant que cela donne une page correcte, même si ce n'est pas une pratique recommandée.

Par exemple, le fichier xmp02.php qui contient


     <html>
       <head>
          <title> (gH) : deuxième exemple en PHP</title>
       </head>
       <body>
         <ul>
           <li> Un</li&gt;
           <?php echo "<li>Deux </li&gt;" ;
              echo "</ul>" ;
           ?>
       </body>
     </html>
     

est syntaxiquement correct, alors que le marqueur <?php commence avant que le marqueur </ul> termine la liste (ce qui est normal, ici, puisque c'est PHP qui termine la liste). Cette pratique, possible certes, n'est pas une bonne pratique. Il vaut mieux faire écrire à PHP des fragments de code XHTML valides dits self contained.

On peut ouvrir et fermer PHP plusieurs fois dans une même page, comme dans


     <html><head>
     <?php echo " <title>troisième exemple</title> " ; ?></head>
     <body><ul><li> Un </li>
     <?php echo "<li>Deux </li>" ;
        echo "</ul>" ;
     ?>
     </body></html>
     

En termes de sécurité, PHP est intéressant car c'est le serveur qui interprète la page. L'utilisateur ne voit que la page produite. Ainsi, la demande de l'affichage du texte source de la page précédente donne


     
     <html>
       <head>
          <title>troisième exemple</title>
       </head>
       <body>
          <ul>
          <li> Un  </li>
          <li>Deux </li>
          </ul>
       </body>
     </html>
     

comme si toute le texte avait été écrit "normalement".

2. Eléments du langage de PHP

2.1 Commentaires, variables, affectations etc.

Un commentaire peut être délimité par /* et */ ou suivre le symbole # ou le symbole double //. L'intérêt d'avoir plusieurs jeux de commentaires est de pouvoir commenter à différents niveaux (titres, commentaires d'explication, petits commentaires brefs de structure...).

Une variable est repérée par le symbole $ et l'affectation se fait avec =. Par exemple $jmois = 0 ; met la valeur 0 dans la variable jmois. PHP n'est pas typé explicitement, ce qui signifie qu'on n'a pas besoin de préciser le type d'une variable. En interne, PHP utilise les types integer, float, string, array et object.

Les variables chaines de caractères utilisent les deux jeux de délimiteurs ' et " ainsi que les séquences escape comme \n\$... Lorsque le délimiteur " est utilisé, les variables à l'intérieur de la chaine sont interpolées, c'est à dire remplacées par leur contenu. Voici un exemple 

$i = 2 ;
echo " \$i vaut $i " ;" # affiche $i vaut 2"
echo " \\$i vaut \$i " ;" # affiche \$i vaut $i"

Les instructions PHP doivent être terminées par des points-virgules. Les définitions de fonction et de classes d'objets ne sont pas des instructions mais des déclarations. Elles ne doivent pas être terminées par des points-virgules (en mettre ne constitue pas toujours une erreur).

Un tableau en PHP est une variable qui utilise des crochets avec une valeur (indice) entre les crochets. L'indice peut être quelconque, ce qui fournit à la fois les tableaux classiques (indice numérique) et les hashs ou tableaux associatifs (indices chaine de caractères). Ainsi $age["Pierre"] = 12 ; met 12 dans le tableau age à l'indice Pierre. La syntaxe explicite "moderne" $t = [1,5,12] ; est aussi acceptée en PHP 7.

La fonction count() renvoie le nombre d'éléments dans le tableau et on accède aux différents éléments du tableau avec each() ou à partir de next() et de prev(). Les tableaux peuvent être triés avec sort(), asort(), arsort(), ksort()...

Certains tableaux sont créés dynamiquement. Ainsi explode(char,chaine) renvoie un tableau où chaque élément correspondant au découpage de la chaine, char étant le séparateur. Par exemple

explode(" ; "," il pleut ; je mange ; tu dors " ) ;

renvoie un tableau a trois éléments dont le premier (situé à l'indice zéro) est il pleut. Si on utilise plus d'un indice, on met des crochets autour de chaque indice. Ainsi l'élément matriciel traditionnel Mi,j d'une matrice se note $M[$i][$j]en PHP.

La fonction print_r permet d'afficher proprement et rapidement tout le contenu d'un objet ou d'un tableau.

Pour mettre le contenu d'un champ issu d'un formulaire dans une variable, il faut passer par le "super-tableau" _GET. Par exemple avec le code HTML suivant, pour récupérer la valeur de l'age,

  <form action=... method="get">  
  Id : <input type="text"   name="age" /><br>
       <input type="submit" value="envoi" /> 
   </form> 

il faut écrire

   $x = $_GET["age"] ; 

mais il serait sans doute plus correct de nommer age la variable associée, soit le code : $age = $_GET["age"] ;. On notera que la fonction isset() permet de tester s'il y a quelquechose au bon indice dans le tableau _GET et que pour la méthode POST, le super-tableau est nommé _POST.

Enfin, les variables d'environnement sont considérées comme des variables PHP normales, même si la fonction getenv() donne accès aux variables systèmes.

Lors de l'affectation, PHP permet de nombreux raccourcis à la C, comme

$a = ++$b = $c; 

ce que nous ne conseillons pas pour des questions de lisibilité.

L'opérateur % renvoie le reste de la division entière (ou modulo). La concaténation de chaine se fait avec un point et $a = $a . $b peut se raccourcir en $a .=  $b. Les opérateurs logiques ont les "doux" noms and , or , xor , ! (not) et les opérateurs de comparaison sont standards : == , <= , >= .

Pour les habitués au C et à PERL, il est possible d'utiliser la construction $a ? $b : $c ; comme raccourci pour l'affection classique if $a then $b else $c, ce que nous ne conseillons pas non plus pour des questions de lisibilité.

Vous trouverez à l'adresse prog01 de nombreux exemples d'affectations et des compléments sur les variables.

2.2 Tests et Boucles

Le test en SI se fait avec if (condition) { ... }. On peut utiliser else pour l'alternative inverse et elseif pour des alternatives multiples. L'instruction switch est également disponible pour les structures de cas générales. Attention : les parenthèses sont obligatoires pour les conditions.

La boucle TANT QUE utilise while (condition) { ... } . La forme do {...} while (condition) réalise la boucle répéter... jusqu'à puisqu'elle effectue le test en fin de boucle.

La boucle pour classique en PHP est for (debut;fin;increment) { ...} mais il existe aussi une boucle foreach.

Une bonne habitude à prendre est de consulter le manuel de PHP (php.net pour avoir le détail des instructions et fonctions PHP. On y trouve aussi des exemples de script, comme pour la page sur foreach.

Vous trouverez à l'adresse prog02 de nombreux exemples sur les tests et les boucles.

2.3 Sous-programmes

Un sous-programme en PHP est forcément une fonction, déclarée par function Nom (liste d'Arguments) { ... ; } .

La valeur renvoyée éventuellement doit être spécifiée par return. Pour envoyer plus d'une valeur, il faut soit convertir le tout en chaine de caractères ("sérialiser"), soit renvoyer un tableau explicite comme dans return array($i, $j).

Les arguments d'une fonction sont obligatoires sauf s'ils ont une valeur par défaut. Le passage par référence plutôt que par valeur se fait en rajoutant & soit dans l'en-tête de la fonction soit au moment de l'appel. Si l'argument est suivi de = valeur, il s'agit d'un paramètre facultatif et ce qui suit le symbole égal sera pris comme valeur par défaut. Si on met le symbole @ devant le nom d'une fonction, le message d'erreur éventuel (en cas d'erreur) n'est pas affiché.

Vous trouverez à l'adresse prog03 de nombreux exemples sur les tableaux et les définitions de fonctions.

2.4 Objets

Les objets en PHP, disponibles depuis PHP 4, utilisent le paradigme de classe, comme C et Java (et non pas de le paradigme de prototype comme le fait Javascript). S'il y n'a pas de typage explicite, il y a déclaration des données (ou attributs, propriétés) avec le mot-clé var et déclaration des méthodes (ou fonctions propres) via le mot-clé function. Les constructeurs (new), instanciations et autres manipulations sont donc "classiques". Voici un exemple de programmation objet en PHP 7 :


     <?php
         class ind {
     
           var $nom ;                // attribut
     
           function __construct($unNom="inconnu") {    // constructeur en PHP4 ; en PHP5, ce serait function __construct($unNom="inconnu")
             $this->nom = $unNom ;
           } # fin de fonction ind
     
           function qui() {          // méthode
             echo " le nom de la personne est \"$this->nom\" \n" ;
           } # fin de fonction qui
     
         } # fin de classe ind
     
         ###################################
     
         class indj extends ind {  // individu jeune est une sous-classe de individu
     
           var $surn ; // surnom
     
           function __construct($unNom,$unSurNom="") {
     
               $this->nom  = $unNom ; # autre possibilité : parent::ind($unNom) ;
               $this->surn = $unSurNom ;
     
           } # fin de fonction ind
     
           function qui() {          // méthode surchargée
             parent::qui() ;         // appel de la méthode parent
             echo " et son surnom est \"$this->surn \"\n" ;
           } # fin de fonction qui
     
         } # fin de classe indj
     
         # exemple d'individu
     
         $jd = new ind("Jean") ;
         $jd->qui() ;
     
         echo "\n" ;
     
         ###################################
     
         # exemple d'individu jeune
     
         $je = new indj("Marie","p'tite Marie") ;
         $je->qui() ;
     
         echo "\n" ;
     
         ###################################
     
         # affichage "readable"
     
         echo "Voici Jean\n" ;
         echo " " ;
         print_r($jd) ;
     
         echo "Et marie \n" ;
         print_r($je) ;
     
         echo "Jean sérialisé :\n" ;
         $o1 = serialize($jd) ;
         print($o1) ;
     
         echo "Et marie\n" ;
         $o2 = serialize($je) ;
         print($o2) ;
     
     ?>
     

Résultat de son exécution en ligne de commandes :


      le nom de la personne est "Jean"
     
      le nom de la personne est "Marie"
      et son surnom est "p'tite Marie "
     
     Voici Jean
      ind Object
     (
         [nom] => Jean
     )
     Et marie
     indj Object
     (
         [surn] => p'tite Marie
         [nom] => Marie
     )
     Jean sérialisé :
     O:3:"ind":1:{s:3:"nom";s:4:"Jean";}Et marie
     O:4:"indj":2:{s:4:"surn";s:12:"p'tite Marie";s:3:"nom";s:5:"Marie";}
     
     

Depuis PHP 5, le modèle objet a été revu et complété. Les données (ou attributs) et les fonctions (ou méthodes) peuvent être déclarées public, private ou protected. Les constructeurs et destructeurs utilisent les noms explicites __construct (au lieu du nom de classe en PHP 4) et __destruct. Le manuel officiel de PHP, nommé oop5 est assez détaillé pour les objets. De plus on trouve de nombreux documents sur le Web qui détaille les objets en PHP, comme ce wikibook, les transparents de M. Slater(version locale, les transparents de 2007-Montreal(version locale, ou d'autres livres trouvés avec Google si on cherche php oo programming filetype:pdf.

Une présentation courte de la couche objet et au passage des méthodes "magiques" se trouve dans le cours php-objets de notre collègue David LESAINT que nous remercions ici pour ce document.

2.5 Encodages

Lorsqu'un navigateur demande une page à un serveur, celui-ci envoie une entête ou header qui peut contenir une déclaration d'encodage. Il peut alors y avoir conflit avec l'indication d'encodage (charset) fourni dans l'attribut content de l'élément meta. Pour éviter cela, il est possible d'utiliser l'instruction header de PHP, sans doute comme première instruction. Vous pouvez consulter nos deux programmes forceiso et forceutf pour vérifier que même le titre est accentué, en UTF comme en ISO8859. Les codes-sources sont respectivement source forceiso et source forceutf. Pour ce dernier fichier, vous devriez voir dans le code-source des caractères bizarres comme é au lieu de é car c'est de l'UTF.

Remarque : il faut bien sûr s'assurer que l'éditeur de textes que l'on utilise code bien les caractères avec le "bon" encodage car une page Web ne peut s'afficher correctement que si les 3 informations suivantes sont cohérentes (4 si on compte l' encoding en cas de déclaration XML) :

  1. l'encodage indiqué par le header ;
  2. l'encodage indiqué dans l'élément meta ;
  3. l'encodage utilisé par l'éditeur de textes.

Nous fournissons dans la petite bibliothèque de fonctions PHP dites conceptuelles accessibles via std.php une solution "propre" comme celle nommée debutPage() pour assurer cette cohérence d'encodage.

2.6 Sessions

Le protocole HTTP est un protocole sans mémoire. Ceci signifie que si vous demandez la page Web a.php il va y avoir exécution du programme correspondant sur le serveur, avec ses variables et ses affichages éventuels, mais qu'à la fin du programme, toutes les variables de ce programme disparaissent et que dès lors HTTP ne se "souvient plus" de ce qu'il y avait comme variables. Pourtant, dans certains cas, on aimerait conserver une trace de ce qui a été défini ou choisi, comme dans le cas du "panier" lors d'achats sur internet. Pour conserver des variables et leur valeur d'une page à l'autre, PHP fournit la notion de session, assez bien expliquée dans le manuel PHP à la rubrique book.session. En deux mots : dès le début de la page on écrit session_start() ; et ensuite on peut utiliser le «super tableau» nommé $_SESSION. Pour y stocker des objets, il faut sans doute les convertir en une représentation caractère adaptée avec serialize().

2.7 Documentation

Même si PHP n'est pas typé explicitement, PHP a des fonctions spécialisées pour chaque type de variable. Par exemple, pour les tableaux il y a count(), sort()  pour les chaines de caractères, il y a strlen(), strtoupper()... Pour chaque rubrique d'utilisation des fonctions, et pour chaque type, il y a des dizaines de fonctions. Il est important de parcourir le manuel PHP pour éviter de mal reprogrammer une fonction déjà existante. Vous pouvez utiliser le tableau suivant tant que vous n'êtes pas familiarisé avec le manuel.

index des rubriques chaines de caractères tableaux
expressions régulières objets fichiers et OS

Il serait illusoire de vouloir apprendre ou maitriser rapidement PHP de par la profusion de ces fonctions : il y en a en gros plus de 3 000 dans le "coeur" de PHP. Et avec des noms parfois incohérents, des syntaxes pas toujours standard... C'est pourquoi nous conseillons d'utiliser des éditeurs "évolués" pour écrire du PHP, comme Geany qui est capable d'afficher la liste des fonctions PHP dès qu'on en saisit les premières lettres...

Si PHP affiche des pages Web via HTML, il est également capable de produire du PDF via des bibliothèques de fonctions dédiées.

3. Programmation classique en PHP

3.1 Exemple 1 : un bonjour complet

Rappelons que ce premier programme doit afficher le mot "Bonjour" puis demander à l'utilisateur son prénom et lui dire au revoir, en affichant la date, l'heure et le prénom en majuscules.

L'affichage du mot Bonjour et la saisie du prénom ne relèvent pas vraiment de PHP, c'est le rôle d'un formulaire HTML. Une version minimale pour cette saisie est


     <html>
     
           <head>
              <title> (gH) : programme BONJOUR en PHP, partie 1 :
                             formulaire de saisie du prénom </title>
           </head>
     
           <body>
             <form action="bonjour.php" method="get" >
             <p>
             <font color="red">Bonjour</font>.
             Quel est votre nom ?
             <input type="text" name="prenom" />
             <input type="submit" value=" envoi ! " />
             </p>
             </form>
         </body>
     
      </html>
     

Lorsque l'utilisateur clique sur le bouton "envoi !", la machine transmet l'URL http://.../bonjour.php?prenom=XXXXXX correspond au texte entré dans le champ du prénom (ou http://.../bonjour.php?prenom= si le champ est vide). Signalons qu'il est d'ailleurs possible d'entrer directement cette URL "à la main" dans le navigateur, ce qui permet de tester le programme même sans formulaire, possibilité que nous exploiterons avec le prochain exemple.

Un programme PHP de réponse minimal est


      <html>
     
                <head>
                   <title> (gH) : programme BONJOUR en PHP,
                                  partie 2 : réponse </title>
                </head>
     
                <body>
                <?php
                   $prenom = "" ;
                   if (isset($_GET["prenom"])) { $prenom = $_GET["prenom"] ; } ;
                   if ($prenom=="") { $nom = " bel inconnu " ; }
                               else { $nom = $prenom  ; } ;
                   $ladate  = date("d/m/Y") ;
                   $lheure  = date("h:i") ;
                   $nomMaj  = strtoupper($nom) ;
                   echo "<p> Le $ladate à $lheure, au revoir, $nomMaj.</p>" ;
                ?>
                </body>
     
          </html>
     
     

Mais on préférera sans doute une version plus habillée, avec des styles CSS, ce qui est plus du ressort d'HTML que de PHP.

Vous pouvez tester ici ce programme.

3.2 Exemple 2 : Table de multiplication

D'habitude, le programme table de multiplication vient demander un nombre (ou utiliser la valeur passée en paramètre). Ici nous ne ferons pas de formulaire, car nous utiliserons la valeur passée sur la ligne de l'URL (avec un rappel du passage de paramètre si l'URL est entrée telle quelle).


     
      <html>
      <head>
         <title> (gH) : programme TABLE (version 1) en PHP </title>
      </head>
      <?php
     
      function aide() {
     
      echo "pour voir la table de N, écrivez au bout de l'URL<br>";
      echo "le symbole ? suivi de n=N. Ainsi pour la table de 5,<br>";
      echo "à la suite de http://.../table.php3 il faut mettre ?n=5.";
     
      } ; # fin de fonction aide
     
      function tdm($vn) {
          echo " <h1>Table de multiplication de $vn</h1> " ;
          echo "<xmp>" ;
          for ($i=1;$i<=10;$i++) {
              $fi = sprintf("   %3d ",$i) ;
              $fp = sprintf("   %6d ",$i*$vn) ;
              echo "   $fi  fois   $vn   =   $fp\n" ;
          } ; # fin de pour i
          echo " </xmp> " ;
      } ; # fin de fonction tdm
     
      ?>
      <body>
      <?php
         if ($n=="") { aide()  ; } else { tdm($n) ; } ;
      ?>
      </body>
      </html>
     

Il est possible de passer plusieurs paramètres, par exemple pour gérer la largeur de l'affichage. Le passage de paramètres, commencé par le symbole ? avec un couple variable=valeur se prolonge par le symbole & suivi d'un autre couple variable=valeur. C'est ce qui est rappelé dans la fonction aide(). Nous profitons alors du passage de paramètre par défaut de PHP dans l'appel de la fonction tdm() dans cette deuxième version :


     <html>
        <head>
           <title> (gH) : exemple MOYENNE en PHP </title>
        </head>
     
        <?php  function aide() { ?>
     
      pour voir la table de N, écrivez au bout de l'URL<br>
      le symbole ? suivi de n=N. Ainsi pour la table de 5,<br>
      à la suite de http://.../table.php3 il faut mettre ?n=5.<p>
     
      vous pouvez aussi passer le paramèetre largeur d'affichage ;
      en utilisant & pour séparer les paramètres.<br>
      par exemple http://.../table.php3?n=123456789&largeur=15
     
           <?php   } ; # fin de fonction aide
     
              function tdm($vn,$larg=6) {
                  echo " <h1>Table de multiplication de $vn</h1> " ;
                  echo "<xmp>" ;
                  for ($i=1;$i<=10;$i++) {
                      $fi = sprintf("   %3d ",$i) ;
                      $fp = sprintf("   %$larg"."d",$i*$vn) ;
                      echo "   $fi  fois $vn   =   $fp\n" ;
                  } ; # fin de pour i
                  echo " </xmp> " ;
              } ; # fin de fonction tdm
     
           ?>
     <body>
     <?php
        if     ($n=="")       { aide()  ; }
        elseif ($largeur=="") { tdm($n) ; }
        else                  { tdm($n,$largeur) ; } ;
     ?>
     </body>
     </html>
     

Vous pouvez tester ici ce programme.

3.3 Exemple 3 : Calcul de moyennes de classe

Il s'agit ici de calculer la moyenne de notes lues dans un fichier. Nous allons en fait proposer soit d'entrer les noms et notes dans une zone texte soit d'envoyer le fichier. Nous n'utiliserons qu'un seul fichier nommé moyenne.php qui s'appellera lui-même avec divers paramètres. Le programme principal vient seulement choisir le sous-programme à exécuter en fonction du paramétre mode, soit le texte :


     <?php
          if     ($mode=="")                 { saisie()  ;}
          elseif ($mode=="saisieFormulaire") { saisieForm();  }
          elseif ($mode=="calculFormulaire") { gereCalculs(1,$valeur);}
          elseif ($mode=="saisieFichier")    { saisieFic();}
          elseif ($mode=="calculFichier")    { gereCalculs(2,"");}
          else                               { pbMode();} ;
     ?>
     

La saisie est un simple formulaire qui vient relancer le script moyenne.php avec la bonne valeur pour le paramètre mode, soit :


     <?php function saisie() {
          debutPageHtml(1," Moyenne, partie 1 : saisie ") ;
     ?>   <h1>Donnez votre choix :</h1>     <ul>
          <li><a href="moyenne.php3?mode=saisieFormulaire">
              calcul sur texte du formulaire</a></li>
          <li><a href="moyenne.php3?mode=saisieFichier">
              calcul sur fichier-texte</a></li>
          </ul></body></html>
     <?php   } ; # fin de fonction saisie ?>
     

La fonction debutPageHtml() gère le document (avec les bons tags de début <html>, <body> etc.). Chaque saisie particulière utilise son formulaire HTML :


     <?php
        function saisieForm() {
             debutPagehtml(2," Moyenne, partie 2.1 :
                         saisie sur formulaire " ) ;
        ?>   <h1>Saisie des valeurs par formulaire</h1>
             <form action="moyenne.php3">
             <input type=hidden name="mode" value="calculFormulaire" />
             <textarea name="valeur" rows=10 cols=35>
                  Durand H. * 9 14 12
             </textarea>
             <input type="submit" value ="envoi" /></form></body></html>
        <?php   } ; # fin de fonction saisieForm
     
        function saisieFic() { global $nomfic, $nomfic_name ;
             debutPageHtml(3," Moyenne, partie 2.2 :
                            calcul sur fichier " ) ;
        ?>   <form enctype="multipart/form-data" action="moyenne.php3"
                                               method="post">
             <input type="hidden" name="mode" value="calculFichier" />
             <input type="hidden" name="max_file_size" value="1000" />
             <font size="4">
             Indiquez votre fichier  <input type="file" name="nomfic" />
             <input type="submit" value="envoi" /></font>
             </form>
             </body></html>
        <?php   } ; # fin de fonction saisieFic ?>
     

La gestion des calculs consiste à appeler le sous-programme calculs avec comme paramètre une chaine de caractère qui contient toutes les valeurs entrées. Dans le cas d'une saisie dans le formulaire, on dispose tout de suite de cette variable. Dans le cas de la saisie sur fichier local, on vient lire le fichier et transférer son contenu dans cette variable. Nous avions convenu pour le format d'entrée de séparer le nom des notes par une étoile (mais pas d'imposer un nombre de notes). La partie calculs vient lire la variable caractère par caractère, remplaçant au passage les sauts de ligne par des espaces et découpe en mots la variable, en affectant là où il faut dès que l'étoile est trouvée. Pour les affichages, nous faisons appel à la même fonction puisque nous trions les tableaux in situ définies comme des variables globales.

Vous pouvez tester ici ce programme.

4. Exemples spécifiques en PHP

4.1 Tableaux associatifs et Expressions régulières

Une fois la syntaxe de base de PHP maitrisée, il reste à bien savoir utiliser les tableaux associatifs et les expressions régulières, parce que le code PHP devient alors concis et efficace.

Pour les tableaux, nous conseillons le lien tutoriel-7 sur www.apprendre-php.com, ce qui amène à l'instruction foreach. En ce qui concerne les expressions régulières, sur le siteduzero.com on trouve une gentille introduction qu'on pourra compléter par la page du wiki français et du wiki anglais , par le tutorial de phpcodeur, puis par des exemples orientés Web via php-regex-library et enfin, on trouvera de nombreux liens techniques à la page essential-guide sans oublier le fameux testeur de regexp nommé regexp.zug et notre mini-tuteur sur les expressions régulières.

Les expressions régulières trouvent naturellement leur place dans le test des valeurs saisies par les utilisateurs dans les formulaires des pages Web mais on s'en sert aussi beaucoup aussi lors de la lecture de fichiers. Il faut savoir qu'en plus des fonctions classiques sur fichiers comme fopen(), fgets() et fclose(), PHP fournit des fonctions "intéressantes" et plus récentes comme file_get_contents(). Rappelons au passage que PHP sait lire n'importe quelle URL comme un fichier en lecture seule, ce qui permet de lire par programme PHP toutes les pages web de tous les sites du monde... en seulement quelques milliards d'heures !

Voici quelques exemples pour les tableaux associatifs et les expressions régulières :


     <?php
     
          $ages = array("pierre"=>5,"eva"=>100,"jean"=>12) ;
     
          $ages = array("pierre"=>5,"marie"=>10,"jean"=>12) ;
     
          foreach ($ages as $cle=>$valeur) {
            echo "$cle  a  ".sprintf("%2d",$valeur)." ans\n" ;
          } ; # fin pour chaque age
     
          /*
     
            Affichage :
     
             pierre  a   5 ans
             marie   a  10 ans
             jean    a  12 ans
     
     
          */
     
          $inputAge1  = 35    ;
          $inputAge2  = "oui" ;
     
          if (preg_match("/[0-9]+/",$inputAge1))  { echo "$inputAge1 est un entier \n" ; } ;
          if (!preg_match("/[0-9]+/",$inputAge2)) { echo "$inputAge2 n'est pas un entier \n" ; } ;
     
          /*
     
            Affichage :
     
             35 est un entier
             oui n'est pas un entier
     
          */
     
          $phrase = " En 1968, il y a eu plus de 534 manifestations de jeunes de 20 ans ou plus " ;
     
          preg_match("/[0-9]{3,}/",$phrase,$res1) ;
          echo "res1 " ;
          print_r($res1) ;
     
          preg_match("/([0-9]{3,})/",$phrase,$res2) ;
          echo "res2 " ;
          print_r($res2) ;
     
          preg_match_all("/([0-9]{3,})/",$phrase,$res3) ;
          echo "res3 " ;
          print_r($res3) ;
     
          preg_match_all("/plus de [0-9]+ .*de (.*?) /",$phrase,$res4) ;
          echo "res4 " ;
          print_r($res4) ;
     
          preg_match_all("/plus de [0-9]+ .*?de (.*?) /",$phrase,$res5) ;
          echo "res5 " ;
          print_r($res5) ;
     
          /*
     
     
          Affichage :
          ---------
     
          res1 Array
          (
              [0] => 1968
          )
     
          res2 Array
          (
              [0] => 1968
              [1] => 1968
          )
     
          res3 Array
          (
              [0] => Array
                  (
                      [0] => 1968
                      [1] => 534
                  )
     
              [1] => Array
                  (
                      [0] => 1968
                      [1] => 534
                  )
     
          )
     
          res4 Array
          (
              [0] => Array
                  (
                      [0] => plus de 534 manifestations de jeunes de 20
                  )
     
              [1] => Array
                  (
                      [0] => 20
                  )
     
          )
     
       res5 Array
          (
              [0] => Array
                  (
                      [0] => plus de 534 manifestations de jeunes
                  )
     
              [1] => Array
                  (
                      [0] => jeunes
                  )
          )
     
     
     
          */
     
          ?>
     

4.2 Nombre de fichiers dans un répertoire

PHP dispose de fonctions pour interagir avec le système d'exploitation. Par exemple la fonction dir() renvoie une variable (une instance d'objet en fait) de type répertoire. On peut donc lui appliquer la méthode read() et la méthode close(). Comme son nom l'indique, read() permet de lire les entrées du répertoire, y compris . et .. (sous Unix). Plus précisément, read() lit au premier appel la premier entrée du répertoire, puis l'entrée courante dans le répertoire à partir de la précédente pour les appels suivants, le pointeur de position étant conservé en interne par PHP.

Pour compter le nombre de fichiers dans un répertoire, il suffit d'appeler la fonction dir() en lui passant comme paramètre le nom du répertoire à consulter puis à exécuter une boucle sur l'appel de la fonction read(). Par exemple, sur notre système, nous avons un répertoire Php/ qui contient deux sous répertoires, Documentation/ et Programmes/. Nous avons donc écrit une fonction dirstat() pour compter leur nombre de fichiers.

Ainsi le code suivant


     <?php function dirstat($nomdir) {
     
          # calcule le nb de fichiers dans le répertoire
     
          $d  = dir($nomdir) ;
          $nbf = 0 ;
           while ($entry=$d->read()) {
              $nbf = $nbf +1 ;
           } ; # fin tant que
           $d->close() ;
           return $nbf-2 ;
     
          } # fin fonction dirstat
     
          $dirbase = "/home/Gh/Info/Cours/Php/" ;
          echo "<font size=+5>Comptages sur les fichiers
                      du répertoire $dirbase</h1> " ;
     
          $cdir = $dirbase ;
          $nbf = dirstat($cdir) ;
          echo   "<font size=+5>racine : $nbf fichiers<p>" ;
     
          $ldir = "Documentation/" ;
          $cdir = $dirbase.$ldir ;
          $nbf  = dirstat($cdir) ;
          echo   "<font size=+5>$ldir : $nbf  fichiers<p>" ;
     
          $ldir = "Programmes/" ;
          $cdir = $dirbase.$ldir ;
          $nbf  = dirstat($cdir) ;
          echo   "<font size=+5>$ldir : $nbf   fichiers" ;
     
     ?>
     

permet d'obtenir de réaliser un comptage et un affichage qui ressemble à :


     Comptages sur les fichiers
            du répertoire /home/Gh/Info/Cours/Php/
         racine : 30 fichiers
         Documentation/ : 17 fichiers
         Programmes/ : 11 fichiers
     

4.3 Requêtes SQL dont SQLite et MySQL

2017 a vu l'arrivée de PHP 7. Avec cette version de PHP, seul PDO a été conservé pour interfacer SQL. Il faut donc impérativement passer au modèle objet pour dialoguer avec les bases de données. Là encore, nous vous proposons de lire le cours php-bd de notre collègue D. LESAINT pour voir ce formalisme en oeuvre. Nous fournissons toutefois ci-dessous quelques exemples de programmes PHP qui utilisent divers dialectes SQL.

Comme premier exemple, nous utilisons le fichier binaire elf_sqlite3.bin qui contient au format SQLIte3 les données de la table elves décrites ici, soit la structure et les données suivantes :

L'intérêt de SQLITE est que ce gestionnaire de base de données ne requiert ni mot de passe ni administration sophistiquée et qu'il permet de créer des bases de données en mémoire (sans stockage sur disque). C'est idéal en mode développement alors que MySQL sera utilisé en test et en production à moins que pour la production on n'utilise PostgresSQL. Voici comment connaitre le nombre d'enregistrements de la table elves :


     <?php
     
     $nomdb   = "elf_sqlite3.bin"                ;   # fichier
     $bd      = new SQLite3($nomdb)              ;   # objet d'interface
     $req     = " SELECT COUNT(*) FROM elves ; " ;   # requete
     $res     = $bd->query($req)                 ;   # resultat
     $ldr     = $res->fetchArray()               ;   # conversion en tableau associatif
     $nbe     = $ldr["COUNT(*)"]                 ;   # récupération du comptage
     
     echo " Il y a $nbe enregistrements dans la base $nomdb.\n" ;
     ?>
     

L'exécution de ce code db1sqlite.php affiche


      Il y a 99 enregistrements dans la base elf_sqlite3.bin.
     

Comme SQLITE crée le fichier de la base de données s'il n'existe pas, il est prudent de vérifier que le fichier est bien là au bon endroit, sinon SQLITE viendra le recréer, avec aucune donnée. De même, il est possible que la version de PHP utilisée ne supporte pas SQLITE3, il vaut mieux le vérifier, soit le code :


     <?php
     
     if (!class_exists('SQLite3')) {   die("SQLite 3 NOT supported.") ; } ;
     
     $nomdb   = "elf_sqlite3.biner" ;
     
     if (!file_exists($nomdb)==1) {
       echo " Le fichier $nomdb pour la base de données n'existe pas. \n" ;
       exit(-1) ;
     } # fin si
     
     $bd      = new SQLite3($nomdb) ;
     
     ?>
     

Il est prudent de ne pas exécuter des requêtes sans tester que cela se passe bien, avec try/catch. Par exemple, si dans le programme précédent de comptage du nombre d'enregistrements de la table elves on fait la faute de frappe COUNTE(*) au lieu de COUNT(*) alors PHP "se plante".


     <?php # ATTENTION CE PROGRAMME db3sqlite.php CONTIENT UNE ERREUR VOLONTAIRE
     
     $nomdb   = "elf_sqlite3.bin"                   ;   # fichier
     $bd      = new SQLite3($nomdb)                 ;   # objet d'interface
     
     $req     = " SELECT COUNTE(*) FROM elves ; "   ;   # requete
     $res     = $bd->exec($req)                     ;   # resultat
     $ldr     = $res->fetchArray()                  ;   # conversion en tableau associatif
     $nbe     = $ldr["COUNT(*)"]                    ;   # récupération du comptage
     
     echo " Il y a $nbe enregistrements dans la base $nomdb.\n" ;
     ?>
     

     $gh> php db3sqlite.php
     
     PHP Warning:  SQLite3::query(): Unable to prepare statement: 1,
         no such function: COUNTE in /home/gh/public_html/tuteurs/db3sqlite.php on line 8
     
     PHP Fatal error:  Uncaught Error: Call to a member function fetchArray() on boolean in db3sqlite.php:9
     
     Stack trace:
     #0 {main}
       thrown in /home/gh/public_html/tuteurs/db3sqlite.php on line 9
     

Voici le code db4sqlite.php qui intercepte l'erreur :


     <?php
     
     $nomdb   = "elf_sqlite3.bin"                   ;   # fichier
     $bd      = new SQLite3($nomdb)                 ;   # objet d'interface
     
     $req     = " SELECT COUNTE(*) FROM elves ; "   ;   # requete
     try {
       $bd->enableExceptions(true);                 ;   # pour try/catch
       $res = $bd->exec($req)                       ;   # resultat
     } catch (Exception $e) {
       echo " Probleme de requete : ". $e->getMessage()."\n" ;
       die(" STOP.\n") ;
     } ; # fin de try/catch
     
     # si on arrive ici, c'est que la requete est OK
     
     $res     = $bd->query($req)                    ;   # resultat
     $ldr     = $res->fetchArray()                  ;   # conversion en tableau associatif
     $nbe     = $ldr["COUNT(*)"]                    ;   # récupération du comptage
     
     echo " Il y a $nbe enregistrements dans la base $nomdb.\n" ;
     ?>
     

      Probleme de requete : no such function: COUNTE
      STOP.
     

La couche objet nommée PDO bien détaillée dans le manuel PHP fournit une interface commune aux divers gestionnaires de bases de données.

Nous suppons pour l'exemple que MySQL contient une table ELF dans la base statdata accessible en lecture pour l'utilisateur anonymous, mot de passe anonymous. Voici comment y accéder :


     <?php
     
     $nombd = "elf" ;
     $bd    = new PDO("mysql:localhost;dbname=statdata;","anonymous","anonymous") or die("non !") ;
     
     try {
       $bd-> setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION) ;
       $res = $bd->query("SELECT COUNT(*) FROM statdata.$nombd ") ;
     } catch (Exception $e) {
       echo "Problème : ".$e->getMessage()."\n" ;
       die("STOP.\n") ;
     } ; # fin de catch
     
     $ldr = $res->fetch(PDO::FETCH_ASSOC)       ;
     $nbe = $ldr["COUNT(*)"]                    ;   # récupération du comptage
     echo " Il y a $nbe enregistrements dans la base $nombd.\n" ;
     
     ?>
     

PDO permet donc d'utiliser SQLite et MySQL avec le même code, ici db1pdo.php :


     <?php
     
     $mode = "TEST" ; # mettre "DEVT" pour que PDO utilise SQLite
     $mode = "DEV"  ; # mettre "TEST" pour que PDO utilise MySQL
     
     echo " MODE : $mode \n\n" ;
     
     if ($mode=="DEV") { # en développement :
        $nomdb    = "elf_sqlite3.bin"                    ;   # fichier
        $nomtable = "elves" ;                            ;   # table
        $bd       = new PDO("sqlite:$nomdb")             ;   # objet d'interface
     } else { # en test :
        $nomdb     = "statdata"                          ;   # fichier
        $nomtable  = "elf" ;                             ;   # table
        $dsn       = "mysql:localhost;dbname=$nomdb;"    ;   # pour mysql
        $ano       = "anonymous"                         ;   # user/password
        $bd        = new PDO($dsn,$ano,$ano) or die("non !") ;
        $bd->query(" USE $nomdb") ;                      ;   # choix de la base
     } ; # fin si
     
     $req     = " SELECT COUNT(*) FROM $nomtable ; "     ;   # requete
     
     try {
       $bd->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION) ;
       $res = $bd->query($req)                           ;   # resultat
     } catch (Exception $e) {
       echo " Probleme de requete COUNT : ". $e->getMessage()."\n" ;
       die(" STOP.\n") ;
     } ; # fin de try/catch
     
     # si on arrive ici, c'est que la requete est OK
     
     $ldr     = $res->fetch(PDO::FETCH_ASSOC)           ;   # conversion en tableau associatif
     $nbe     = $ldr["COUNT(*)"]                        ;   # récupération du comptage
     
     echo " Il y a $nbe enregistrements dans $nomdb/$nomtable.\n" ;
     
     # les 9 personnes FEMME de moins de 18 ans
     # SELECT iden, sexe, age FROM elf WHERE sexe=1 AND age<18 ;
     
     $ageMax   = 18 ;
     $codeSexe =  1 ; # 1 pour Femme, 0 pour Homme
     $champ1   = "IDEN" ; # à titre d'exemple
     $cnd      = " sexe=$codeSexe AND age < $ageMax " ;
     $que      = " SELECT IDEN, SEXE, AGE FROM $nomtable " ;
     $que     .= "        WHERE $cnd ORDER BY age" ;
     
     try {
       $bd->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION) ;
       $res = $bd->query($que)                           ;   # resultat
     } catch (Exception $e) {
       echo " Probleme de requete SELECT : ". $e->getMessage()."\n" ;
       die(" STOP.\n") ;
     } ; # fin de try/catch
     
     echo "IDEN SEXE AGE\n" ;
     foreach ($res as $ldr) {
       echo $ldr[$champ1]."  ".$ldr["SEXE"]."   ".$ldr["AGE"]."\n" ;
     } # fin de pour chaque
     
     ?>
     

      Il y a 99 enregistrements dans statdata/elf.
     IDEN SEXE AGE
     M012  1   11
     M025  1   14
     M028  1   15
     M034  1   12
     M037  1   15
     M049  1   17
     M090  1   15
     M093  1   13
     M096  1   17
     

5. Exemples plus techniques en PHP

On trouvera ici une collection de scripts plus techniques et plus originaux.

    5.1 Dictionnaires d'un fichier texte

    5.2 Classification hiérarchique de données bactériologiques

    5.3 Identification automatique de vecteurs d'absence-présence

    5.4 Graphiques avec Jpgraph

    5.5 Diaporamas en PHP

    5.6 Site LEADB (bioinformatique)

    5.7 Production de pdf via LaTeX

    5.8 Tracé de graphe mathématique via Dot

6. En guise de conclusion sur PHP

Ce texte est un petit tuteur et nous n'avons fait qu'aborder grossièrement PHP. Ainsi, nous n'avons pas expliqué en détail comment on peut utiliser php -a en ligne de commandes afin de profiter du mode interactif, ni comment on peut écrire des scripts qui s'exécutent dans un terminal, avec $argc paramètres mis dans le tableau PHP $argv , ni comment on peut interfacer le DOM de HTML et de XML avec PHP, ni comment on peut lire, écrire, gérer du XML, par exemple avec l'extension simplexml de PHP. On trouvera ici des exemples de tels traitements XML en PHP.

De même, rien n'a été dit sur les liens entre Javascript et PHP donc rien sur AJAX , ni avec les graphiques de type PNG, GIF ou SVG. Si on sait que PHP peut gérer les divers protocoles de transmissions de données, on peut en déduire qu'avec PHP on peut écrire des gestionnaires FTP ou des gestionnaires de messagerie en PHP ou des systèmes de transaction de cartes bancaires en PHP. Vous comprendrez que PHP est une mine, une source... à preuve la liste de toutes les fonctions PHP.

Pourtant, il faut certainement être un peu critique, car PHP est un fils un peu «indigne» de PERL, (voir par exemple contrast), PHP est un langage assez mal conçu et encore plus mal implémenté, même s'il est utilisé pratiquement partout...

Nous finirons donc par vous inviter à lire notre petite bibliothèque de fonctions dites conceptuelles accessibles via  std.php . Ce tuteur est bien sûr écrit avec ces fonctions, c'est pourquoi il n'y a aucune balise HTML apparente dans le code-source PHP de la page. Vous pouvez le vérifier avec le lien en fin de page.

Nous vous encourageons aussi à lire nos exercices corrigés de Licence 2ème année pour le développement Web, niveau élémentaire et niveau avancé , nos exercices corrigés de Licence Pro, nos tuteurs de divers langages ainsi que nos cours avec exercices corrigés sur XML, les langages de scripts et les frameworks de développement, car on y parle encore de PHP...

Enfin, il faudrait sans doute aussi parler de programmation concise en PHP comme ici, il faudrait évoquer les tests en PHP par exemple avec phpunit ou encore l'automatisation des interfaces Web avec des headless browsers, disons avec puphpeteer pour finir avec les frameworks de développement PHP comme indiqués ici afin d'avoir une idée un peu plus complète de ce que représente PHP aujourd'hui.

Bonne lecture !

 

Code-source PHP de cette page.

 

 

retour gH    Retour à la page principale de   (gH)