TD1 – Introduction à PHP Hello World, objets et formulaires
Bienvenus dans le premier TD de PHP, qui vous fera découvrir un serveur Web sous Docker, initialiser le dépôt Git de vos TDs, utiliser PhpStorm, apprendre les bases du langage PHP et exécuter vos premiers scripts PHP.
Mettre en place un serveur Web sous Docker
Commençons par vous faire découvrir un serveur Web sous Docker.
Allez sur la page du dépôt Serveur Web
Docker,
et faites le tutoriel d’installation et de configuration qui se trouve dans la
partie Tutoriel
> Premier contact
. Vous ne devez normalement pas y passer
plus de 30 minutes.
Git et IDE pour PHP
Configuration de Git
Ce cours de PHP est aussi l’occasion de continuer à manipuler le gestionnaire de version Git, qui conversera la chronologie de toutes vos modifications. Commençons par nous assurer que Git est bien configuré sur vos machines.
-
Nous allons configurer Git pour qu’il connaisse votre nom et votre adresse email (étudiante), ce qui sera utile quand vous travaillerez en groupe pour savoir qui a enregistré quelle modification :
git config --global user.name "Votre Prénom et Nom" git config --global user.email "votreemail@etu.umontpellier.fr"
-
Au cas où vous utilisez le protocole HTTPS pour vous connecter à un dépôt Git, vous aurez besoin d’exécuter d’abord la commande suivante pour que
git clone
marche.# Pour anticiper une erreur due aux certificats de l'IUT # "server certificate verification failed" git config --global http.sslverify false
Remarque : nous vous recommandons de vous connecter à vos dépôts Git par SSH.
Vous allez maintenant créer votre copie du dépôt Git des TDs PHP afin de pouvoir enregistrer vos modifications dedans.
- Allez sur la page web du dépôt Git initial des TDs PHP.
- Créez votre copie du dépôt en cliquant en haut à droite sur le bouton Fork.
- Dans Project URL, changer Select a namespace par votre login IUT, puis cliquez sur Fork project en bas de la page.
- (Optionnel mais recommandé) Si vous êtes sur une nouvelle machine, recréez une clé SSH et déposez-la sur GitLab en reprenant le tout début du tutoriel Git de 1ère année.
- Sur la page de votre fork, copiez l’adresse pour cloner le dépôt que l’on trouve en cliquant sur le bouton bleu Code.
- Depuis un terminal dans le dossier
~/public_html
, faitesgit clone
de l’adresse de la question précédente.
PhpStorm
PHP est un langage de programmation donc utilisez un environnement de développement. Vous ne codez pas du Java avec BlocNotes, c’est pareil pour PHP. Nous coderons donc notre PHP sous PhpStorm de la suite logicielle JetBrains (comme Intellij Idea).
Si vous utilisez un portable fourni par l’IUT, PhpStorm est déjà installé. Sinon, installez-le à l’aide de ces instructions dans les compléments du TD1.
Cloner un dépôt Git sous PhpStorm
- Lancez PhpStorm.
- Connectez-vous pour activer la licence académique que vous avez eu l’an dernier. Pour la
retrouver, connectez-vous au site de
JetBrains.
Sinon, remplissez ce formulaire en utilisant votre adresse universitaire pour bénéficier d’une licence académique.
Quelques minutes après, vous recevrez un email de confirmation suivi d’un second email d’activation où vous devrez accepter les conditions d’utilisation et choisir un nom d’utilisateur et un mot de passe. Conservez précieusement ces informations, car c’est grâce à elles que vous pourrez importer votre licence sur toutes les machines que vous allez utiliser (chez vous, à l’IUT etc). - Cliquez en haut à droite sur Open puis sélectionnez le dossier
tds-php/TD1
(qui deviendra un projet PHPStorm).
Documentations de PhpStorm
- Documentation officielle en anglais
- Documentation à l’IUT de Intellij Idea (proche de PhpStorm)
Autre IDE
Si vous le souhaitez fortement, vous pouvez aussi utiliser d’autres IDE. VSCode est une bonne alternative, mais il manque des fonctionnalités PHP. Notez cependant que nous n’assurons pas le support d’autres IDE.
Accédez à vos pages web
Nous avons vu lors du cours 1 le fonctionnement du World Wide Web sur le modèle de client & serveur HTTP. Mettons en pratique tout cela !
Une page HTML de base
- Le dépôt Git contient la page
public_html/tds-php/TD1/page1.html
suivante<!DOCTYPE html> <html> <head> <title> Insérer le titrer ici </title> <meta charset="utf-8" /> </head> <body> Un problème avec les accents à é è ? <!-- ceci est un commentaire --> </body> </html>
-
Ouvrez le dossier
public_html/tds-php/TD1
avec le gestionnaire de fichier puis double-cliquez surpage1.html
pour l’ouvrir dans votre navigateur. Remarquez que l’URL de la page est file://…/public_html/tds-php/TD1/page1.html.Que fait le gestionnaire de fichier quand on double-clique ?
Que signifie le file au début de l’URL ?
Est-ce qu’il y a une communication entre un serveur et un client HTTP ?Réponses (surlignez le texte caché à droite): Le gestionnaire de fichier ouvre page1.html dans le navigateur en tant que fichier local. Autrement dit, le navigateur va lire le fichier page1.html directement sur le disque dur. C’est la signification de file au début de l’URL. Du coup, le navigateur n’envoie pas de requête HTTP, et n’attends pas de réponse en retour.
-
Vous souvenez-vous comment fait-on pour qu’une page Web soit servie par le serveur HTTP de Docker (à l’URL http://localhost/tds-php/TD1/page1.html) ?
Réponse : Les pages Web doivent être enregistrées dans le dossier public_html de votre répertoire personnel.
Ouvrez donc
page1.html
depuis le navigateur en tapant l’URL dans la barre d’adresse.Est-ce qu’il y a une communication entre un serveur et un client HTTP maintenant ?
Comment fait-on pour voir la page Web brute (code source), et non son rendu HTML par le navigateur ?
Réponses (surlignez le texte caché à droite): Cette fois-ci, l’URL commence par http et donc le navigateur envoie une requête HTTP à l’URL demandée. Le navigateur reçoit une réponse HTTP qui contient une page HTML. Puis, le navigateur affiche le rendu HTML de la page. Pour voir le code source HTML, il faut faire un clic droit sur la page, puis Affichez le code source (ou Ctrl+U).
Notre première page PHP
-
Le dépôt Git contient la page
public_html/tds-php/TD1/echo.php
suivante<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title> Mon premier php </title> </head> <body> Voici le résultat du script PHP : <?php // Ceci est un commentaire PHP sur une ligne /* Ceci est le 2ème type de commentaire PHP sur plusieurs lignes */ // On met la chaine de caractères "hello" dans la variable 'texte' // Les noms de variable commencent par $ en PHP $texte = "hello world !"; // On écrit le contenu de la variable 'texte' dans la page Web echo $texte; ?> </body> </html>
-
Ouvrez cette page dans le navigateur directement depuis votre gestionnaire de fichiers OU de façon équivalente avec une URL en
file://
comme :
file://…/public_html/TD1/echo.php.Que se passe-t-il quand on ouvre un fichier PHP directement dans le navigateur ?
Pourquoi ?
Ça vous rappelle le cours 1 j’espère ?
Réponses (surlignez le texte caché à droite): Un navigateur ne sait que faire d’un script PHP. Du coup, soit il vous demande comment l’ouvrir, soit il le télécharge directement. -
Ouvrez cette page dans le navigateur dans un second onglet en passant par le serveur HTTP de Docker :
http://localhost/tds-php/TD1/echo.phpQue se passe-t-il quand on demande un fichier PHP à un serveur HTTP ?
Regardez les sources de la page Web (Clic droit, code source ouCtrl-U
) pour voir ce qu’a vraiment généré PHP.
N’hésitez pas à relire la partie du cours 1 concernée.Réponses (surlignez le texte caché à droite): Quand le serveur Web reçoit une requête HTTP pour un fichier PHP, il exécute le script PHP et renvoie la page Web générée par le script.
Les bases de PHP
Différences avec Java
- Le code PHP doit être compris entre la balise ouvrante
<?php
et la balise fermante?>
- Les variables sont précédées d’un
$
- Il n’est pas obligatoire de déclarer le type d’une variable (cf. plus loin dans le TD)
Les chaînes de caractères
Différentes syntaxes existent en PHP ; selon les délimiteurs que l’on utilise, le comportement est différent.
Avec guillemets simples
Les chaînes de caractères avec simple quote '
sont conservées telles
quelles (pas de caractères spéciaux \n
…). Les caractères
protégés sont '
et \
qui doivent être échappés avec un anti-slash comme ceci
\'
et \\
;
La concaténation de chaînes de caractères se fait avec l’opérateur point .
$texte = 'hello' . 'World !';
Avec guillemets doubles
Pour simplifier le code suivant
$prenom="Helmut";
echo 'Bonjour ' . $prenom . ', ça farte ?';
PHP propose une syntaxe de chaîne de caractères entourée de double quotes "
qui permet d’écrire
$prenom="Helmut";
echo "Bonjour $prenom, ça farte ?";
Les chaînes de caractères avec double quotes "
peuvent contenir :
- des variables (qui seront remplacées par leur valeur),
- des sauts de lignes,
- des caractères spéciaux (tabulation
\t
, saut de ligne\n
). - Les caractères protégés sont
"
,$
et\
qui doivent être échappés avec un anti-slash\
comme ceci :\"
,\$
et\\
;
Astuce : En cas de problèmes avec le remplacement de variables, rajoutez
des accolades autour de la variable à remplacer. Cela marche aussi bien pour
les tableaux "{$tab[0]}"
, les attributs "{$objet->attribut}"
et les
fonctions "{$objet->fonction()}"
.
Documentation : Les chaînes de caractères sur PHP.net
Qu’écrivent chacun des echo
suivants ?
$prenom = "Marc";
echo "Bonjour\n " . $prenom;
echo "Bonjour\n $prenom";
echo 'Bonjour\n $prenom';
echo $prenom;
echo "$prenom";
Testez votre réponse en rajoutant ce code dans echo.php
.
Astuce:
-
Vous pouvez aussi tester ce code dans le terminal (sans passer par un serveur Web et un navigateur). Pour cela, écrivez votre script dans
echo.php
(n’oubliez pas la balise ouvrante<?php
en début de fichier). Puis, dans le terminal, exécutezphp echo.php
.Ce fonctionnement est plus proche de ce que vous auriez fait en Python avec
python script.py
, ou en Java avecjavac program.java
puisjava program
.
Affichage pour le débogage
Les fonctions print_r
et var_dump
affichent les informations d’une variable
et sont très utiles pour déboguer notamment les tableaux ou les objets.
La différence est que print_r
est plus lisible car var_dump
affiche plus de
choses (les types).
Les tableaux associatifs
Les tableaux en PHP peuvent aussi s’indexer par des entiers ou des chaînes de caractères :
-
Pour initialiser un tableau, on utilise la syntaxe
$utilisateur = array( 'prenom' => 'Juste', 'nom' => 'Leblanc' );
ou la syntaxe raccourcie équivalente
$utilisateur = [ 'prenom' => 'Juste', 'nom' => 'Leblanc' ];
-
On peut ajouter des cases à un tableau :
$utilisateur['passion'] = 'maquettes en allumettes';
Note : Le tableau
$utilisateur
contient plusieurs associations. Par exemple, il associe à la chaîne de caractères'prenom'
la chaîne de caractères'Juste'
.
Dans cette association,'prenom'
s’appelle la clé (ou index) et'Juste'
la valeur. -
On peut rajouter facilement un élément “à la fin” d’un tableau avec
$utilisateur[] = "Nouvelle valeur";
-
Pour le remplacement de variable dans des chaînes de caractères délimités par des guillemets doubles, on utilise une des syntaxes suivantes
// Syntaxe avec {$...} echo "Je m'appelle {$utilisateur['nom']}"; echo "Je m'appelle {$utilisateur["nom"]}"; // Syntaxe simplifiée // Attention, pas de guillemets autour de la clé "nom" echo "Je m'appelle $utilisateur[nom]";
-
Notez l’existence des boucles
foreach
pour parcourir les paires clé/valeur des tableaux.foreach ($monTableau as $cle => $valeur){ //commandes }
La boucle
foreach
va boucler sur les associations du tableau. Pour chaque association,foreach
va mettre la clé de l’association dans la variable$cle
et la valeur dans$valeur
puis exécuter les commandes. Par exempleforeach ($utilisateur as $cle => $valeur){ echo "$cle : $valeur\n"; }
va afficher ceci
prenom : Juste nom : Leblanc passion : maquettes en allumettes 0 : Nouvelle valeur
Remarque : La boucle
foreach
est indispensable pour parcourir les indices et valeurs d’un tableau indexé par des chaînes de caractères.
Il existe aussi bien sûr une bouclefor
classique si le tableau est indexé uniquement par des entiersfor ($i = 0; $i < count($monTableau); $i++) { echo $monTableau[$i]; }
Pour comprendre
foreach
autrement, le code suivantforeach ($monTableau as $cle => $valeur){ //commandes }
est équivalent à
for ($i = 0; $i < count(array_keys($monTableau)); $i++) { $cle = array_keys($monTableau)[$i]; $valeur = $monTableau[$cle]; //commandes }
Source : Les tableaux sur php.net
Exercices d’application
-
Dans votre fichier
echo.php
, créez trois variables$nom
,$prenom
et$login
contenant des chaînes de caractères de votre choix ; -
Créez la commande PHP qui écrit dans votre fichier le code HTML suivant (en remplaçant bien sûr le nom par le contenu de la variable
$nom
…) :<p> Utilisateur Juste Leblanc de login leblancj </p>
-
Faisons maintenant la même chose mais avec un tableau associatif
utilisateur
:-
Créez un tableau
$utilisateur
contenant trois clés"nom"
,"prenom"
et"login"
avec les valeurs de votre choix ; -
Utilisez l’un des affichages de débogage (e.g.
var_dump
) pour vérifier que vous avez bien rempli votre tableau ; -
Affichez le contenu de “l’utilisateur-tableau” au même format HTML
<p> Utilisateur Juste Leblanc de login leblancj </p>
-
-
Maintenant nous souhaitons afficher une liste d’utilisateurs :
-
Créez une liste (un tableau indexé par des entiers)
$utilisateurs
de quelques “utilisateurs-tableaux” ; -
Utilisez l’un des affichages de débogage (e.g.
var_dump
) pour vérifier que vous avez bien rempli$utilisateurs
; -
Modifier votre code d’affichage pour écrire proprement en HTML un titre “Liste des utilisateurs :” puis une liste (
<ul><li>...</li></ul>
) contenant les informations des utilisateurs.
-
-
Pour déboguer votre script, il est parfois pratique d’afficher la sortie brute du script. Vous souvenez-vous comment faire ?
Réponse (surlignez à droite): Affichez donc le code source de la page. -
Rajoutez un cas par défaut qui affiche “Il n’y a aucun utilisateur.” si la liste est vide.
(On vous laisse chercher sur internet la fonction qui teste si un tableau est vide) -
Enregistrez votre travail dans Git via PhpStorm.
La programmation objet en PHP
PHP était initialement conçu comme un langage de script, mais est passé Orienté Objet à partir de la version 5. Plutôt que d’utiliser un tableau, créons une classe pour nos utilisateurs.
Un exemple de classe PHP
-
Créer un fichier Utilisateur.php avec le contenu suivant
<?php class Utilisateur { private $login; private $nom; private $prenom; // un getter public function getNom() { return $this->nom; } // un setter public function setNom($nom) { $this->nom = $nom; } // un constructeur public function __construct( $login, $nom, $prenom, ) { $this->login = $login; $this->nom = $nom; $this->prenom = $prenom; } // Pour pouvoir convertir un objet en chaîne de caractères public function __toString() { // À compléter dans le prochain exercice } } ?>
Notez les différences avec Java :
- Pour accéder à un attribut ou une fonction d’un objet, on utilise le
->
au lieu du.
de Java. - En PHP,
$this
est obligatoire pour accéder aux attributs et méthodes d’un objet. - On doit mettre le mot-clé
function
avant de déclarer une méthode - Le constructeur ne porte pas le nom de la classe, mais s’appelle
__construct()
. - En PHP, on ne peut pas avoir deux fonctions avec le même nom, même si elles ont un nombre d’arguments différent. En particulier, il ne peut y avoir au maximum qu’un constructeur.
- Pour accéder à un attribut ou une fonction d’un objet, on utilise le
-
Créez des getter et des setter pour
$prenom
et$login
;
(PhpStorm peut les générer automatiquement pour vous avec Clic droit > Generate) -
L’intérêt des setter est notamment de vérifier ce qui va être écrit dans l’attribut. Comme le login est limité à 64 caractères, codez un setter qui ne stocke que les 64 premiers caractères du login dans l’objet. Mettez aussi à jour le constructeur pour ne garder que les 64 premiers caractères.
(Documentation PHP : fonctionsubstr
substring). -
Remplissez
__toString()
qui permet de convertir un utilisateur en chaine de caractères. -
Testez que votre classe est valide pour PHP : la page générée par le serveur Web Docker à partir de
Utilisateur.php
ne doit pas afficher d’erreur.
Demandez donc votre page au serveur Web http://localhost/tds-php/TD1/Utilisateur.php. -
Enregistrez votre travail sous Git à l’aide de PhpStorm.
Utilisation de la classe Utilisateur
Nous voulons utiliser la classe Utilisateur
dans un autre script testUtilisateur.php
. Il faut donc inclure le fichier Utilisateur.php
, qui contient la déclaration de la classe de Utilisateur
, dans testUtilisateur.php
pour pouvoir l’utiliser.
Require
PHP a plusieurs façons d’inclure un fichier :
-
require "dossier/fichier.php"
: inclut et exécute le fichier spécifié en argument, ici"dossier/fichier.php"
. Autrement dit, tout se passe comme si le contenu defichier.php
avait été copié/collé à la place durequire
.
Renvoie une erreur si le fichier n’existe pas. -
require_once "dossier/fichier.php"
: fait de même querequire
mais la différence est que si le code a déjà été inclus, il ne le sera pas une seconde fois.
Ceci est particulièrement utile pour inclure une classe car cela assure qu’on ne l’inclura pas deux fois.
Notez qu’il existe include
et include_once
qui ont le même effet mais
n’émettent qu’un warning si le fichier n’est pas trouvé (au lieu d’une erreur).
Exercice
-
Créez un fichier testUtilisateur.php contenant le squelette HTML classique (
<html>
,<head>
,<body>
…) -
Dans la balise
<body>
, on va vouloir créer des objetsUtilisateur
et les afficher :-
Incluez
Utilisateur.php
à l’aide derequire_once
comme vu précédemment ; -
Initialisez une variable
$utilisateur1
de la classeUtilisateur
;
- Affichez cet utilisateur avec un
echo
, ce qui appellera implicitement la méthode__toString()
.
-
-
Testez votre page sur le serveur Web :
http://localhost/tds-php/TD1/testUtilisateur.php
Déclaration de type
Optionnellement, on peut déclarer les types de certaines variables PHP :
- les arguments d’une fonction
- la valeur de retour d’une fonction
- les attributs de classe
Ces types sont vérifiés à l’exécution, contrairement à Java qui les vérifie à la compilation.
La déclaration de type est cruciale pour que l’IDE devine correctement le type des objets et pour que vous puissiez bénéficier pleinement de l’autocomplétion de l’IDE.
Exemple :
class Requete {
// Déclaration de type d'un attribut
string $url;
string $methode; // GET ou POST
}
class Reponse {
int $code; // 200 OK ou 404 Not Found
string $corps; // <html>...
}
// Déclaration de type d'un paramètre de fonction (Requete)
// et d'un retour de fonction (Reponse)
function ServeurWeb(Requete $requete) : Reponse {
// Corps de la fonction ...
}
- Mettez à jour
Utilisateur.php
pour déclarernom
,prenom
etlogin
commestring
dans- les attributs de classes,
- les arguments des setters,
- les sorties des getters,
- les arguments du constructeur,
- le type de sortie de
__toString()
.
Note : Pour pouvoir utiliser les déclarations de type, il faut indiquer à PhpStorm que vous voulez utiliser la version 8.3 du langage PHP. Pour ceci, cliquez en bas à droite de l’IDE sur
PHP: *.*
pour basculer versPHP: 8.3
. -
Testez que PHP vérifie bien les types : dans
testUtilisateur.php
, appelez une fonction qui attend en argument unstring
en lui donnant à la place un tableau (le tableau vide[]
par exemple). Vous devez recevoir un message comme suitPHP Fatal error: Uncaught TypeError: Utilisateur::__construct(): Argument #1 ($nom) must be of type string, array given
- Enregistrez votre travail sous Git à l’aide de PhpStorm.
Interaction avec un formulaire
-
Créez un fichier formulaireCreationUtilisateur.html, réutilisez l’entête du fichier echo.php et dans le body, insérez le formulaire suivant :
<form method="get" action="creerUtilisateur.php"> <fieldset> <legend>Mon formulaire :</legend> <p> <label for="login_id">Login</label> : <input type="text" placeholder="leblancj" name="login" id="login_id" required/> </p> <p> <input type="submit" value="Envoyer" /> </p> </fieldset> </form>
-
Souvenez-vous (ou relisez le cours 1) de la signification des attributs
action
de<form>
etname
de<input>
Rappels supplémentaires :
-
L’attribut
for
de<label>
doit contenir l’identifiant d’un champ<input>
pour qu’un clic sur le texte du<label>
vous amène directement dans ce champ. -
l’attribut
placeholder
de<input>
sert à écrire une valeur par défaut pour aider l’utilisateur.
-
-
Créez des champs dans le formulaire pour pouvoir rentrer le nom et le prénom de l’utilisateur.
-
Souvenez-vous (ou relisez le cours 1) de ce que fait un clic sur le bouton “Envoyer”.
Vérifiez en cliquant sur ce bouton.Comment sont transmises les informations ?
Comment s’appelle la partie de l’URL contenant les informations ? -
Prenez l’habitude d’enregistrer régulièrement votre travail sous Git. En cliquant sur l’icône Git en bas à gauche de PhpStorm, vous pouvez retrouver l’historique de vos enregistrements passés.
-
Créez un fichier
creerUtilisateur.php
:- Aidez-vous si nécessaire du cours 1 pour savoir comment récupérer l’information envoyée par le formulaire.
- Vérifiez que
creerUtilisateur.php
reçoit bien des informations dans le query string. Pour cela, vérifiez que le tableau$_GET
n’est pas vide (comment afficher un tableau facilement ?). - En reprenant du code de
testUtilisateur.php
, faites quecreerUtilisateur.php
affiche les informations de l’utilisateur envoyée par le formulaire. - Bien sûr, testez votre page en la demandant au serveur Web.
-
Afin d’éviter que les données du formulaire n’apparaissent dans l’URL, modifiez le formulaire pour qu’il appelle la méthode POST :
<form method="post" action="creerUtilisateur.php">
et côté
creerUtilisateur.php
, mettez à jour la récupération des paramètres :- Souvenez-vous (ou relisez le cours 1) de par où passe l’information envoyée par un formulaire de méthode POST ;
- Changez
creerUtilisateur.php
pour récupérer l’information envoyée par le formulaire ; - Essayez de retrouver l’information envoyée par le formulaire avec les outils de développement (Onglet Réseau).
-
Avez-vous pensé à enregistrer vos modifications sous Git ? Faites-le notamment en fin de TD pour retrouver plus facilement où vous en êtes la prochaine fois.