Les exercices suivants sont les exercices du premier chapitre de cours de PHP. Pour tous les exercices, nous allons utiliser le serveur local. Étant donné la configuration des ordinateurs de l’IUT, le serveur local ne peut accéder qu’aux fichiers du répertoire /home/$USER/public_html. Pour accéder à ces documents en passant par le serveur local, il faut alors taper l’url :

http://localhost/~VOTRE_NUMERO_ETUDIANT/chemin/nom_du_fichier

chemin correspond au chemin où se trouve votre fichier à partir du répertoire public_html. Par exemple, si votre numéro d’étudiant est le 001 et si vous créez un dossier TP1 dans votre répertoire public_html et un fichier exercice1.php dans TP1, pour accéder à ce fichier, vous devez spécifier l’adresse Web :

http://localhost/~001/TP1/exercice1.php

Attention : Les données stockées dans le répertoire public_html sont supprimées à chaque redémarrage de l’ordinateur. Le moyen le plus simple pour que vos documents soient sauvegardés tout en étant accessibles via le serveur local est d’utiliser le task runner robo. Correctement configuré, ce task runner va vous permettre de synchroniser votre répertoire de travail (situé dans la partie sauvegardée de vos documents) avec le répertoire /home/$USER/public_html. Cette synchronisation implique que chaque changement effectué dans votre répertoire de travail sera automatiquement appliqué dans le répertoire public_html.

Pour configurer facilement le task runner, il faut le configurer une première fois puis l'activer à chaque début de séance.

Configuration du task runner

Ouvrez un terminal et tapez les commandes suivantes :

 
cd ~/Bureau/Mes_Montages/$USER
git clone https://github.com/mathieuLacroix/R301.git

Activation en début de séance

Ouvrez un terminal et tapez les commandes suivantes :

 
    cd ~/Bureau/Mes_Montages/$USER/R301
    code web/
    robo sync
  

Le répertoire /home/$USER/public_html contient alors une copie du répertoire ~/Bureau/Mes_Montages/$USER/R301/web qui est mise à jour à chaque modification de ce dernier.

Attention : La synchronisation se fait tant que la commande robo sync s'exécute. Il ne faut donc pas fermer le terminal ou tuer le processus. De plus, vous devez mettre tout votre code uniquement dans le répertoire ~/Bureau/Mes_Montages/$USER/R301/web.

Remarque : Comme l’ensemble des réponses aux exercices contiennent du code PHP, il n’est pas possible d’ouvrir le fichier directement à l’aide du navigateur. Il est donc impératif de passer par le serveur local.

Exercice 1 : Premiers pas en PHP

Voici un code php.

<!doctype html>
<html>
<head>
<title> <?php echo 'Premiers pas en PHP'; ?> </title>
<meta charset="utf-8"/>
</head>
<body>
<h1> Mes premiers pas en PHP </h1>
<?php $tps=2; echo '<p> Je débute depuis '; echo $tps; echo ' heures... </p>';?>
<p> Mais cela a l'air intéressant <?php echo '!' ?> </p>
<?php echo '
<h2> Vive le PHP </h2>
<p> Les pages vont pouvoir être dynamiques! </p>
'; ?>
<p> Encore quelques paragraphes </p>
echo '<p> Avant dernier paragraphe </p>';
<p> Voilà, c'est terminé! </p>
</body>
</html>

Répondre aux questions suivantes :

  1. Donner dans ce fichier les parties correspondant à du code PHP et à du code HTML.

  2. Si ce fichier s’appelle exo1.php, et s’il est stocké sur le site Web www.exemple.org dans le répertoire PremierTP, comment “exécuter” ce fichier ? Que donne son exécution ? Ceci est-il valide ? Pourquoi ? Corriger alors le problème.

  3. Remplacer les trois instructions echo de la ligne 9 par une seule.

Exercice 2 : Inclusion d’en-tête et pied de page

Le langage PHP permet d’inclure des fichiers dans d’autres. Ceci permet alors de décomposer un code HTML ou PHP en plusieurs parties logiques et d’insérer ensuite ces différentes parties dans un fichier PHP.

  1. Créer un fichier debut_code_html.php contenant tout le code HTML jusqu’à la balise <body> incluse.

  2. Créer un fichier fin_code_html.php contenant les balises </body></html>.

  3. Créer un fichier code.php contenant un titre et un paragraphe et incluant les fichiers debut_code_html.php et fin_code_html.php.

  4. Modifier le fichier debut_code_html.php pour que le titre de l’onglet (balise <title>) dépende de la valeur de la variable $title définie dans le fichier code.php.

Exercice 3 : Instruction echo et concaténation

Dans le code PHP suivant, afficher, à l’aide d’une seule instruction PHP le paragraphe “J’ai 3 chats et 2 chiens, ce qui me fait 5 animaux”. Les valeurs 3, 2 et 5 affichées dépendent des valeurs des variables $chats et $chiens. Le faire une fois en utilisant uniquement les apostrophes et une fois en utilisant uniquement les guillemets.

Remarque : Le code utilise les fichiers debut_code_html.php et fin_code_html.php de l’exercice 2 pour définir une page Web complète. Il est recommandé de les utiliser pour chaque exercice du TP.

<?php

$title = "Exercice 3";
require "debut_code_html.php";


$chats = 3;
$chiens = 2;

// TO DO : afficher le paragraphe en fonction des variables $chats et $chiens

require "fin_code_html.php";

Exercice 4 : Tableaux

Considérons le tableau PHP suivant.

$t = [
    'english',
    'first'=>'html', 
    2 => 'css', 
    'best'=>'php', 
    'javascript',
    5 => 'jQuery'
];
  1. Quelles sont les clés du tableau ? Quelles sont les valeurs ?

  2. À l’aide de l’instruction var_dump($t);, vérifier si les clés et les valeurs sont bien celles prédites.

  3. Afficher la liste des valeurs du tableau dans une liste ordonnée.

  4. Afficher la liste des clés du tableau dans une deuxième liste ordonnée.

Exercice 5 : Tableau à deux dimensions

On définit le tableau suivant :

$personnes = [
  'mdupond' => ['Prénom' => 'Martin', 'Nom' => 'Dupond', 'Age' => 25, 'Ville' => 'Paris'       ],
  'jm'      => ['Prénom' => 'Jean'  , 'Nom' => 'Martin', 'Age' => 20, 'Ville' => 'Villetaneuse'],
  'toto'    => ['Prénom' => 'Tom'   , 'Nom' => 'Tonge' , 'Age' => 18, 'Ville' => 'Epinay'      ],
  'arn'     => ['Prénom' => 'Arnaud', 'Nom' => 'Dupond', 'Age' => 33, 'Ville' => 'Paris'       ],
  'email'   => ['Prénom' => 'Emilie', 'Nom' => 'Ailta' , 'Age' => 46, 'Ville' => 'Villetaneuse'],
  'dask'    => ['Prénom' => 'Damien', 'Nom' => 'Askier', 'Age' => 7 , 'Ville' => 'Villetaneuse']
];
  1. Quelles sont les clés du tableau $personnes et leur type ? De quel type sont les valeurs de ce tableau ? Quelle est la valeur associée à ‘toto’ ?

  2. Comment accéder à la valeur 33 dans le tableau ? À la valeur ‘Epinay’ ? Au tableau contenant les valeurs ‘Damien’, ‘Askier’, 7, ‘Villetaneuse’ ?

  3. Écrire une fonction prenant en paramètre un tableau (avec une structure similaire à $personnes) et l’affichant sous forme d’une table HTML. Le code HTML obtenu avec le tableau $personnes doit être :

     <table>
         <tr>
             <td>Martin</td>
             <td>Dupond</td>
             <td>25</td>
             <td>Paris</td>
         </tr>
         <tr>
             <td>Jean</td>
             <td>Martin</td>
             <td>20</td>
             <td>Villetaneuse</td>
         </tr>
         <tr>
             <td>Tom</td>
             <td>Tonge</td>
             <td>18</td>
             <td>Epinay</td>
         </tr>
         <tr>
             <td>Arnaud</td>
             <td>Dupond</td>
             <td>33</td>
             <td>Paris</td>
         </tr>
         <tr>
             <td>Emilie</td>
             <td>Ailta</td>
             <td>46</td>
             <td>Villetaneuse</td>
         </tr>
         <tr>
             <td>Damien</td>
             <td>Askier</td>
             <td>7</td>
             <td>Villetaneuse</td>
         </tr>
     </table>
    
  4. Modifier la fonction précédente pour ajouter une ligne d’en-têtes. Les en-têtes seront les clés du tableau contenu dans la première case. Dans le cas de $personnes, les en-têtes seront Prénom, Nom, Age, Ville.
    Indice : Utiliser array_keys($personnes)[0] pour récupérer la première clé du tableau $personnes.
  5. Vérifier que l’affichage obtenu est correct lorsque la fonction prend en paramètre le tableau suivant :
    $scores = [
      ['Joueur' => 'Camille'  , 'score' => 156 ],
      ['Joueur' => 'Guillaume', 'score' => 254 ],
      ['Joueur' => 'Julien'   , 'score' => 192 ],
      ['Joueur' => 'Nabila'   , 'score' => 317 ],
      ['Joueur' => 'Lorianne' , 'score' => 235 ],
      ['Joueur' => 'Tom'      , 'score' => 83  ],
      ['Joueur' => 'Michael'  , 'score' => 325 ],
      ['Joueur' => 'Eddy'     , 'score' => 299 ]
    ];
    

Exercice 6 : Tableau à deux dimensions

On considère les deux tableaux suivants :

$tabMagazines = [
  'le monde'              => ['frequence' => 'quotidien', 'type' => 'actualité', 'prix' => 220],
  'le point'              => ['frequence' => 'hebdo'    , 'type' => 'actualité', 'prix' => 80 ],
  'causette'              => ['frequence' => 'mensuel'  , 'type' => 'féminin'  , 'prix' => 180],
  'politis'               => ['frequence' => 'hebdo'    , 'type' => 'opinion'  , 'prix' => 100],
  'le monde diplomatique' => ['frequence' => 'mensuel'  , 'type' => 'analyse'  , 'prix' => 60 ],
  'libération'            => ['frequence' => 'quotidien', 'type' => 'actualité', 'prix' => 190],
];

$tabMagazinesAbonne = ['le monde', 'le monde diplomatique'];
  1. Afficher sur une ligne le nom de tous les magazines triés par ordre alphabétique et séparés par des virgules, sans faire de boucle. Vous utiliserez des fonctions déjà existantes telles que implode, sort et array_keys que vous trouverez dans le manuel php.

  2. Afficher séparés par des virgule les noms des quotidiens (et uniquement ceux-ci).

  3. Afficher les magazines exactement de la façon suivante en supposant qu’il peut y avoir beaucoup de magazines et beaucoup de propriétés associées :
    • le monde (quotidien, actualité, 220)
    • le point (hebdo, actualité, 80)
    • causette (mensuel, féministe, 180)
    • politis (hebdo, opinion, 100)
    • le monde diplomatique (mensuel, analyse, 60)
  4. En utilisant le tableau $tabMagazinesAbonne contenant le nom des magazines d’un abonné, calculer le prix total de son abonnement.

Exercice 7 : Objets

L’objectif de cet exercice est de développer une classe permettant la gestion d’une TODO liste (liste de tâches à réaliser).

  1. Créer la classe TODOList contenant un attribut privé $to_dos, correspondant à un tableau contenant la liste des tâches à réaliser (chaque case correspond à une tâche qui est une chaîne de caractères). Les clés correspondront aux indices. Cette classe sera définie dans le fichier TODOList.php.

  2. Définir un constructeur ne prenant pas d’argument et initialisant une TODO liste vide.

  3. Définir la méthode add_to_do prenant en paramètre une chaîne de caractères (correspondant à une tâche). Si cette chaîne n’est pas vide et n’est pas constituée uniquement d’espaces, la méthode ajoute cette tâche à la fin de la TODO liste.

  4. Définir la méthode remove_to_do prenant en paramètre un indice et supprimant la tâche associée à cet indice dans la TODO liste.

  5. Définir la méthode is_empty retournant true s’il n’y a aucune tâche, et false sinon.

  6. Définir la méthode get_html retournant une chaîne de caractères correspondant au code HTML d’une liste non ordonnée où chaque item correspond à une tâche. Dans le cas où la TO DO liste est vide, get_html doit renvoyer le paragraphe “Aucune tâche à faire !”.

  7. Créer un script testTDL.php créant une TODO liste avec 4 tâches, l’affichant, supprimant une des tâches puis l’affichant à nouveau. Ajouter des tests pour vérifier que la méthode is_empty fonctionne correctement et qu’une tâche vide ou constituée uniquement d’espaces n’est pas ajoutée à la liste.

Exercice 8 : Expressions régulières

On souhaite écrire des expressions régulières et vérifier qu’un ensemble de chaînes vérifie ou pas une expression régulière.

  1. Définir une fonction check_er prenant en paramètre une expression régulière et un tableau dont les clés sont des chaînes de caractères et les valeurs des booléens indiquant si la clé doit vérifier ou non l’expression régulière. La fonction doit parcourir les chaînes de caractères (clés) du tableau. Pour chaque chaîne, si celle-ci vérifie l’expression régulière alors que la valeur associée dans le tableau est false, ou si elle ne vérifie pas l’expression régulière alors que la valeur est true, la fonction doit afficher un message d’erreur. De plus, la fonction doit afficher le nombre d’erreurs.

    À titre d’exemple, si la fonction check_er est appelée avec l’expression régulière "/php/" et le tableau

     [
       "J'adore le php !" => true,
       "Génial le php !!!" => false,
       "Javascript est mieux" => false,
       "J'adore le javascript" => true
     ]
    

    la fonction doit afficher :

    • ERREUR : “Génial le php !!!” vérifie l’er alors que la valeur est false !
    • ERREUR : “J’adore le javascript” ne vérifie pas l’er alors que la valeur est true !

    Il y a 2 erreurs !

  2. Donner l’expression régulière correspondant à un nombre entier. Il est possible d’avoir un nombre négatif. L’appel de la fonction check_er avec l’expression régulière et le tableau suivant ne doit donner aucune erreur.
     [
         "10" => true,
         "0" => true,
         "-34539" => true,
         "--44" => false,
         "" => false,
         "123a456" => false,
         "10.2" => false
     ]
    
  3. Donner l’expression régulière correspondant à un nombre décimal. On utilisera le symbole . comme séparateur décimal. Pour simplifier, on supposera qu’il y a forcément un chiffre après le séparateur décimal si celui-ci est donné. L’appel de la fonction check_er avec l’expression régulière et le tableau suivant ne doit donner aucune erreur.
     [
         "10" => true,
         "0" => true,
         "-34539" => true,
         "--44" => false,
         "" => false,
         "123a456" => false,
         "10.2" => true,
         "0.001" => true,
         ".001" => true,
         "10." => false
     ]
    
  4. Donner l’expression régulière correspondant aux dates au format JJ/MM/AAAA. Il est possible de ne spécifier qu’un chiffre pour le jour et le mois. L’année contient obligatoirement 4 chiffres.

    Attention : L’expression régulière vérifie si le format correspond à celui demandé, pas si la date donnée est valide. Par exemple 34/78/1234 est considéré comme valide.

    L’appel de la fonction check_er avec l’expression régulière et le tableau suivant ne doit donner aucune erreur.

     [
         "10/10/2021" => true,
         "9/9/1234" => true,
         "90/9/5476" => true,
         "8/23/0014" => true,
         "111/23/0423" => false,
         "12/12/123" => false,
         "1/11234" => false,
         "10/2" => false,
         "1a/2b/8790" => false
     ]
    

Exercice 9 : Passage de paramètres dans l’url

  1. Créer un script nombre.php qui teste s’il existe un paramètre de nom nombre. Si c’est le cas, alors le script teste par une expression régulière si sa valeur est un nombre entier ou pas et affiche cette information.

  2. Tester le script dans les cas suivants :
    • sans passer de paramètre,
    • en passant un paramètre avec un nom différent de nombre,
    • en passant un paramètre nombre de valeur 25,
    • en passant un paramètre nombre de valeur 12a34.

    Dans tous les cas, le script nombre.php ne doit générer aucune erreur.

  3. Créer un formulaire avec un champ de type texte (pour saisir un nombre) et un bouton submit. La soumission du formulaire appellera le fichier nombre.php. Placer ensuite ce formulaire dans le script nombre.php pour pouvoir saisir plusieurs valeurs, le script indiquant à chaque fois si la valeur saisie est un nombre.

Exercice 10 : Sessions et cookies

Attention : cet exercice nécessite d’avoir fait l’exercice précédent car c’est la suite. Il faut modifier le script nombre.php défini dans l’exercice précédent pour effectuer des multiplications.

  1. Utiliser les sessions pour faire la multiplication des nombres saisis dans le formulaire.

  2. Pourquoi est-ce important de vérifier que le nombre saisi correspond à un nombre ? Que se passe-t-il si aucune vérification n’était faite ? Tester en passant au script le paramètre nombre avec la valeur abc.

  3. Modifier le code de manière à pouvoir réinitialiser le produit des nombres en appuyant sur un autre bouton de type submit.

  4. À l’aide des cookies, modifier le script pour qu’à chaque fois que l’on réinitialise un produit, la valeur de ce produit calculé (s’il est différent de 1) soit stocké dans un cookie. Afficher à la fin du script la valeur du dernier produit calculé avant réinitialisation si cette information est disponible.

Exercice 11 : TODO liste

L’objectif de cet exercice est de programmer une page Web (tdl.php) permettant de gérer une TODO liste (liste de tâches à réaliser). Chaque utilisateur se connectant sur la page Web doit pouvoir gérer sa propre TODO liste : créer des tâches, en supprimer et les sauvegarder. L’ajout d’une tâche se fera à l’aide d’un formulaire et la suppression d’une tâche se fera grâce à un lien hypertexte. La sauvegarde de la TODO liste se fera grâce aux cookies. La TODO liste doit être sauvegardée dans les sessions pour être accessible à chaque appel du script. L’instance de la classe TODOList sera stockée dans la variable $_SESSION["tdl"].

Important : Cet exercice utilise la classe TODOList définie dans l’exercice 6. Il faut donc avoir terminé cet exercice avant de commencer celui-ci.

Important : Comme l’objet TODOList est sauvegardé dans la session, il est impératif d’inclure la définition de la classe avant d’activer les sessions. Le fichier tdl.php doit commencer par :

require_once "TODOList.php"; // avant session_start car on stocke un objet TODOList dans la session
session_start();
  1. Créer le script tdl.php. Celui-ci doit :
    • vérifier que la TODO liste est existe dans la session. Si ce n’est pas le cas, il initialise une TODO liste vide qu’il sauvegarde dans la session ;
    • vérifier s’il existe dans l’url un paramètre task. Si ce paramètre existe, alors le script ajoute à la TODO liste une tâche correspondant à la valeur du paramètre task ;
    • afficher la TODO liste.
  2. Créer un formulaire facilitant l’ajout d’une tâche dans la TODO liste.

  3. Modifier la méthode get_html de la classe TODO liste pour que chaque item soit un hyperlien sur le script tdl.php avec le numéro de la tâche comme valeur du paramètre rm.

  4. Modifier le script tdl.php pour permettre la suppression des tâches dans la TODO liste lors d’un clic sur un hyperlien d’une tâche.

  5. Définir les méthodes get_representation et set_representation dans la classe TODOList. La première méthode retournera une chaîne de caractères contenant les différentes tâches séparées par "///" (on suppose qu’aucune tâche contient "///"). La deuxième méthode chargera la liste des tâches (ie, modifiera le tableau to_dos) en fonction de la représentation passée en paramètre.
  6. Modifier le script tdl.php pour permettre de sauvegarder la représentation de la TODO liste dans un cookie lors d’un clic sur un hyperlien (à ajouter dans le script). Modifier l’initialisation de la TODO liste (lorsqu’elle n’est pas dans la session) pour que celle-ci charge la représentation dans le cookie si celui-ci existe. Ajouter un lien supprimant $_SESSION["tdl"] pour vérifier que la sauvegarde via le cookie fonctionne.

Lorsque tous les exercices de ce TP sont compris et terminés, vous pouvez faire les exercices de révision du premier chapitre.