Aller au contenu principal

1) Révisions PHP

Objectifs de la séance

  • Comprendre ce qu'est PHP et en quoi il diffère du HTML.
  • Installer et configurer un environnement de développement local.
  • Savoir créer un fichier PHP, déclarer des variables et afficher du contenu dans le navigateur.
  • Écrire des conditions (if / else) pour adapter l'affichage.
  • Organiser son code en plusieurs fichiers avec require_once.
  • Écrire une fonction réutilisable.

Notions théoriques

PHP, un langage côté serveur

Quand un navigateur demande une page HTML classique, le serveur Web lui envoie le fichier tel quel. Le navigateur lit le HTML et affiche la page.

Avec PHP, le fonctionnement est différent :

  1. Le navigateur demande une page (par exemple index.php).
  2. Le serveur Web détecte l'extension .php et confie le fichier au moteur PHP (l'interpréteur du code PHP).
  3. PHP exécute le code contenu dans le fichier, et produit du HTML en sortie.
  4. Le serveur envoie ce HTML au navigateur.
  5. Le navigateur affiche la page. Il ne voit jamais le code PHP : il reçoit uniquement du HTML.

C'est ce qu'on appelle un langage côté serveur (server-side).

info

Le code PHP n'est jamais visible par l'utilisateur dans le navigateur (contrairement au HTML ou au CSS, qui sont visibles via "Afficher le code source de la page").

Les bases du langage

Balises PHP

Le code PHP est toujours écrit entre les balises d'ouverture <?php et de fermeture ?>. Tout ce qui se trouve en dehors de ces balises est envoyé tel quel au navigateur (comme du HTML normal).

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Ma page</title>
</head>
<body>
<p>Ceci est du HTML classique.</p>
<?php
// Ceci est du code PHP. Il sera exécuté par le serveur.
print "<p>Ceci est généré par PHP.</p>";
?>
</body>
</html>

Variables

En PHP, une variable commence toujours par le signe $, suivi d'un nom (sans espace, sans caractère spécial autre que _). PHP détermine automatiquement le type de la variable en fonction de la valeur qu'on lui attribue.

<?php
$nom = "Lara"; // chaîne de caractères (string)
$pointsDeVie = 100; // nombre entier (integer)
$taille = 1.75; // nombre décimal (float)
$estVivant = true; // booléen (boolean)

Les types principaux à retenir pour le moment :

TypeDescriptionExemple
stringchaîne de caractères"Bonjour"
intnombre entier42
floatnombre décimal3.14
boolvrai ou fauxtrue, false

Affichage

L'instruction print envoie du texte vers le navigateur. On peut y mettre du HTML, car le résultat de PHP est toujours du HTML que le navigateur interprète.

<?php
print "Bonjour";
print "<p>Un paragraphe HTML généré par PHP</p>";

Pour assembler (concaténer) plusieurs morceaux de texte, on utilise le point . :

<?php
$nom = "Lara";
print "<p>Bienvenue, " . $nom . " !</p>";

Conditions

La structure if / else if / else permet d'exécuter des blocs de code différents selon qu'une condition est vraie ou fausse.

<?php
$age = 18;

if ($age >= 18) {
print "<p>Majeur</p>";
} else {
print "<p>Mineur</p>";
}

Les opérateurs de comparaison courants :

OpérateurSignification
==est égal à
!=est différent de
>est supérieur à
<est inférieur à
>=est supérieur ou égal à
<=est inférieur ou égal à

Fonctions

Une fonction est un bloc de code réutilisable auquel on donne un nom. On la définit une fois et on peut l'appeler autant de fois que nécessaire.

<?php
function direBonjour($prenom) {
print "<p>Bonjour, " . $prenom . " !</p>";
}

direBonjour("Lara");
direBonjour("Lara");

Une fonction peut aussi renvoyer une valeur avec return :

<?php
function additionner($a, $b) {
return $a + $b;
}

$resultat = additionner(10, 5);
print "<p>Le résultat est " . $resultat . "</p>";

Inclure un fichier

L'instruction require_once permet d'inclure le contenu d'un fichier PHP dans un autre. C'est indispensable pour organiser son code : au lieu de tout entasser dans un seul fichier, on sépare les responsabilités.

<?php
require_once "fonctions.php";
// Toutes les fonctions définies dans fonctions.php sont maintenant disponibles ici.

Le mot once garantit que le fichier n'est inclus qu'une seule fois, même si require_once est appelé plusieurs fois sur le même fichier. Cela évite les erreurs de redéfinition (par exemple une fonction déclarée deux fois).


Mise en place de l'environnement

Avant de commencer le TP, il faut disposer d'un serveur Web capable d'exécuter du PHP.

Utiliser le serveur intégré de PHP

PHP inclut un petit serveur Web de développement.

Pour utiliser le serveur Web intégré à PHP (builtin), il suffit d'avoir PHP installé sur sa machine.

astuce

Si PHP n'est pas installé, il est suffit de consulter Installer PHP pour les instructions d'installation.

  1. Ouvrir un terminal (ou une invite de commandes).
  2. Se placer dans le dossier du projet (celui qui contiendra les fichiers .php).
  3. Lancer la commande suivante :
php -S localhost:8000
  1. Ouvrir un navigateur et aller à l'adresse http://localhost:8000.

Le serveur affichera automatiquement le fichier index.php s'il existe dans le dossier courant.

Pour vérifier que PHP est bien installé, taper php -v dans le terminal. Si une version s'affiche (par exemple PHP 8.x.x), c'est bon. Sinon, il faut installer PHP.

Vérifier l'installation

Créer un fichier info.php dans le dossier du projet avec le contenu suivant :

<?php
phpinfo();

Ouvrir http://localhost:8000/info.php dans le navigateur. Si une page violette affichant la configuration de PHP apparaît, l'installation fonctionne. Ce fichier peut être supprimé ensuite.


Test de mémorisation/compréhension


Lorsqu'un navigateur demande une page PHP, que reçoit-il exactement du serveur Web ?


Que se passe-t-il pour le texte ou le code HTML situé en dehors des balises `<?php` et `?>` ?


Pourquoi le code PHP n'est-il jamais visible par l'utilisateur via l'option 'Afficher le code source de la page' du navigateur ?


Laquelle de ces déclarations de variable est invalide ?


Comment PHP détermine-t-il le type d'une variable (string, int, float, bool) ?


Quel type PHP sera automatiquement attribué à la variable `$valeur = 1.75;` ?


Quel opérateur est utilisé en PHP pour assembler (concaténer) plusieurs morceaux de texte ?


Est-il possible d'utiliser des balises HTML à l'intérieur de l'instruction `print` ?


Dans le cadre d'une condition, quelle est la différence fondamentale entre les opérateurs `=` et `==` ?


Quel est le rôle de l'instruction `return` à l'intérieur d'une fonction ?


Quelle est la différence principale entre `print` et `return` dans une fonction ?


Pourquoi l'instruction `require_once` inclut-elle le mot `once` ?


Quel est le but principal de l'utilisation de `require_once` dans un projet ?


Comment le serveur Web détecte-t-il qu'il doit confier un fichier au moteur PHP plutôt que de l'envoyer tel quel ?


Si vous lancez le serveur intégré avec `php -S localhost:8000` et qu'aucun fichier n'est spécifié dans l'URL, quel fichier le serveur cherchera-t-il automatiquement ?


Quelle est la commande exacte à taper dans le terminal pour lancer le serveur Web de développement intégré à PHP sur le port 8000 ?


Que permet de vérifier la commande `php -v` exécutée dans le terminal ?


Quel est le résultat attendu dans le navigateur lorsqu'on visite un fichier contenant uniquement `<?php phpinfo(); ?>` ?


Quel opérateur de comparaison signifie 'est différent de' en PHP ?


Que se passe-t-il si on appelle la fonction `direBonjour('Lara');` définie par `function direBonjour($prenom) { print "<p>Bonjour, " . $prenom . " !</p>"; }` ?



TP pour réfléchir et résoudre des problèmes

Créer les fondations du jeu de combat

L'objectif de ce TP est de poser les premières bases d'un jeu de combat que l'on construira au fil des six séances. Pour le moment, il n'y a pas encore de classes ni d'interactions : on apprend simplement à manipuler PHP pour afficher des informations dans le navigateur.

À la fin de cette séance, la page affichera une liste de personnages avec leurs caractéristiques, et un message indiquant leur état (en forme, blessé, mort) adapté en fonction de leurs points de vie.

Étape 1 - Créer le dossier du projet et le premier fichier

Créer un dossier nommé jeu-de-combat (ou tout autre nom de votre choix). C'est dans ce dossier que tous les fichiers du projet seront stockés.

À l'intérieur de ce dossier, créer un fichier nommé index.php. C'est le point d'entrée de l'application : c'est ce fichier que le serveur Web exécutera quand on accède à http://localhost:8000.

Écrire le code suivant dans index.php :

<?php
$nomDuJeu = "Jeu de combat PHP";
print "<h1>Bienvenue dans " . $nomDuJeu . "</h1>";

Lancer le serveur intégré de PHP depuis le dossier du projet :

php -S localhost:8000

Ouvrir http://localhost:8000 dans le navigateur et vérifier que le titre s'affiche correctement.


Bonne pratique - Tester fréquemment

Il est conseillé de toujours tester immédiatement après avoir écrit quelques lignes. Il vaut mieux détecter une erreur quand on vient d'écrire 3 lignes que quand on en a écrit 50.

astuce

Si PHP n'est pas installé, il est suffit de consulter Installer PHP pour les instructions d'installation.

Étape 2 - Déclarer les caractéristiques d'un personnage

On veut représenter un personnage du jeu avec trois informations :

  • son nom (une chaîne de caractères) ;
  • ses points de vie (un nombre entier) ;
  • ses dégâts par tour, aussi appelés DPS (un nombre entier).

Dans index.php, remplacer le contenu par :

<?php
$nomDuJeu = "Jeu de combat PHP";

$nom = "Lara";
$vie = 100;
$dps = 10;

Ajouter ensuite l'affichage de ces informations sous forme de HTML, en utilisant print et la concaténation avec le point ..

L'affichage attendu dans le navigateur est le suivant :


Jeu de combat PHP

Personnage : Lara

Points de vie : 100

Dégâts par tour : 10



Bonne pratique - Noms de variables explicites

Il est conseillé de choisir des noms de variables explicites. $vie est plus lisible que $v, et $dps est un terme courant dans le jeu vidéo (damage per second). Un code lisible est un code qui sera plus facile à maintenir et à faire évoluer.

Étape 3 - Ajouter une structure HTML complète

Pour le moment, le navigateur reçoit des balises HTML (<h1>, <p>...) mais il manque la structure obligatoire d'une page HTML : le <!DOCTYPE>, la balise <html>, le <head> et le <body>.

Modifier index.php pour envelopper le code PHP dans une structure HTML valide. Le code PHP doit se trouver à l'intérieur de la balise <body>.

Ajouter dans le <head> :

  • un encodage UTF-8 (<meta charset="UTF-8">) pour que les accents s'affichent correctement ;
  • un titre de page (<title>) qui apparaîtra dans l'onglet du navigateur ;
  • la langue française (lang="fr" sur la balise <html>).

Bonne pratique - Écrire une structure HTML complète

Il est conseillé de toujours écrire une structure HTML complète et valide, même si le navigateur est capable d'afficher du HTML incomplet. Déclarer l'encodage UTF-8 évite les problèmes d'accents, et préciser lang="fr" aide les outils d'accessibilité à prononcer correctement le contenu.

Étape 4 - Afficher un message selon les points de vie

Le jeu a besoin d'indiquer l'état d'un personnage en fonction de ses points de vie. Voici les règles :

  • Si les points de vie sont strictement supérieurs à 50 : afficher "En pleine forme".
  • Si les points de vie sont entre 1 et 50 (inclus) : afficher "Blessé".
  • Si les points de vie sont à 0 ou en dessous : afficher "Mort".

Ajouter, après l'affichage des caractéristiques du personnage, une condition if / else if / else qui affiche le message approprié dans un paragraphe <p>.

Tester en modifiant la valeur de $vie (par exemple $vie = 30; puis $vie = 0;) et en rechargeant la page pour vérifier que le bon message apparaît à chaque fois.


Bonne pratique - Utiliser des accolades

Il est conseillé de toujours utiliser des accolades { } pour délimiter les blocs if / else, même quand le bloc ne contient qu'une seule instruction. Sans accolades, si l'on ajoute une deuxième instruction plus tard en pensant qu'elle fait partie du bloc, elle sera en réalité exécutée dans tous les cas. C'est une source classique de bugs difficiles à repérer.

Étape 5 - Ajouter un deuxième personnage

Le jeu va mettre en scène plusieurs personnages. Pour le moment, on va simplement en déclarer un deuxième et afficher les deux.

Ajouter un deuxième jeu de variables pour un nouveau personnage (par exemple "Mario", 80 points de vie, 15 DPS). Afficher ses caractéristiques et son état, de la même manière que pour le premier personnage.

On remarque immédiatement le problème : le code d'affichage est dupliqué. On copie-colle les mêmes lignes de print et de if/else pour chaque personnage. C'est exactement ce qu'on va résoudre à l'étape suivante avec les fonctions.


Bonne pratique - Factoriser le code

Quand on constate qu'on copie-colle du code, c'est le signe qu'il faut créer une fonction. Le copier-coller est l'ennemi du développeur : si l'on découvre un bug dans le bloc copié, il faut penser à le corriger à tous les endroits. Avec une fonction, la correction se fait une seule fois. La duplication de code rend la maintenance plus difficile et augmente le risque d'erreurs. Quand on crée une fonction, on centralise la logique dans un seul endroit, ce qui facilite les modifications futures. Cela s'appelle "factoriser" le code.

Étape 6 - Créer une fonction pour éviter la duplication

Créer une fonction nommée afficherPersonnage qui prend trois paramètres : $nom, $vie et $dps. Cette fonction doit afficher les caractéristiques du personnage et son état, exactement comme on le faisait pour chaque personnage à l'étape précédente.

La fonction ne renvoie rien (return n'est pas nécessaire ici) : elle se contente d'afficher du HTML avec print.

Remplacer les blocs dupliqués de l'étape 5 par des appels à cette fonction.

L'affichage dans le navigateur doit être strictement identique à celui de l'étape 5.


Bonne pratique - Noms de fonctions et de paramètres explicites

Une fonction doit avoir un nom qui décrit clairement ce qu'elle fait. afficherPersonnage est explicite. Éviter les noms vagues comme faire() ou traiter(). De même, les paramètres de la fonction ($nom, $vie, $dps) doivent être nommés de manière compréhensible.

Étape 7 - Séparer la fonction dans un fichier dédié

À mesure que le projet grandit, garder tout le code dans un seul fichier devient ingérable. On va séparer la logique (les fonctions) de l'affichage (la page HTML).

Créer un nouveau fichier nommé fonctions.php dans le même dossier que index.php.

Y déplacer la fonction afficherPersonnage (et uniquement cette fonction). Le fichier fonctions.php doit commencer par <?php et ne contenir que la définition de la fonction.

Dans index.php, supprimer la définition de la fonction et la remplacer par une instruction require_once "fonctions.php"; placée au tout début du bloc PHP, avant tout appel à la fonction.

Vérifier dans le navigateur que l'affichage est identique à l'étape 6.


Bonne pratique - Utiliser require_once

Il est conseillé d'utiliser require_once plutôt que require ou include. La variante once garantit que le fichier n'est chargé qu'une seule fois, même si l'instruction apparaît à plusieurs endroits. Cela évite les erreurs du type "Cannot redeclare function..." qui surviennent quand PHP tente de définir la même fonction deux fois.

Étape 8 - Simuler un combat simple

On va maintenant utiliser les variables et les fonctions pour simuler un combat rudimentaire. L'idée : un personnage attaque un autre, ce qui réduit ses points de vie.

Créer une fonction simulerAttaque dans fonctions.php. Cette fonction prend quatre paramètres : le nom de l'attaquant ($nomAttaquant), les DPS de l'attaquant ($dpsAttaquant), le nom de la cible ($nomCible) et les points de vie actuels de la cible ($vieCible).

La fonction doit :

  1. Calculer les nouveaux points de vie de la cible : $vieCible - $dpsAttaquant.
  2. Afficher un message de combat du type : "Lara attaque Lara et inflige 10 dégâts."
  3. Renvoyer (avec return) les nouveaux points de vie de la cible.

Dans index.php :

  1. Déclarer deux personnages avec leurs caractéristiques (nom, vie, DPS).
  2. Afficher les deux personnages avant le combat (avec afficherPersonnage).
  3. Appeler simulerAttaque pour faire attaquer le premier personnage sur le deuxième. Récupérer la nouvelle valeur de vie renvoyée par la fonction et la stocker dans la variable de vie du deuxième personnage.
  4. Afficher les deux personnages après le combat.

L'affichage attendu dans le navigateur est le suivant (les valeurs exactes dépendent des caractéristiques choisies) :


Jeu de combat PHP

Avant le combat

Personnage : Lara

Points de vie : 100

Dégâts par tour : 10

État : en pleine forme

Personnage : Lara

Points de vie : 80

Dégâts par tour : 15

État : en pleine forme

Lara attaque Lara et inflige 10 dégâts.

Après le combat

Personnage : Lara

Points de vie : 100

Dégâts par tour : 10

État : en pleine forme

Personnage : Lara

Points de vie : 70

Dégâts par tour : 15

État : en pleine forme



Bonne pratique - Renvoyer des résultats avec return

Une fonction qui calcule quelque chose doit renvoyer le résultat avec return plutôt que de modifier directement une variable globale. Cela rend la fonction prévisible : on sait ce qu'elle reçoit en entrée et ce qu'elle produit en sortie. Ce principe deviendra encore plus important quand on passera à la programmation orientée objet lors de la prochaine séance.

Étape 9 - Simuler plusieurs tours de combat avec une boucle

Le combat ne s'arrête pas après une seule attaque. On veut simuler plusieurs tours : à chaque tour, le premier personnage attaque le deuxième, puis le deuxième attaque le premier. Le combat s'arrête quand l'un des deux tombe à 0 points de vie ou en dessous.

Créer une fonction simulerCombat dans fonctions.php. Elle prend six paramètres : les nom, vie et DPS des deux personnages.

La fonction utilise une boucle while qui continue tant que les deux personnages ont des points de vie strictement supérieurs à 0. À chaque itération :

  1. Le premier personnage attaque le deuxième (appeler simulerAttaque).
  2. Vérifier si le deuxième personnage est encore en vie. Si oui :
  3. Le deuxième personnage attaque le premier (appeler simulerAttaque).

Après la boucle, afficher le vainqueur (celui qui a encore des points de vie).

Dans index.php, remplacer l'appel unique à simulerAttaque par un appel à simulerCombat.


Bonne pratique - Garantir une condition de sortie pour les boucles

Une boucle while doit toujours avoir une condition de sortie garantie. Ici, à chaque tour, au moins un des deux personnages perd des points de vie, donc la boucle finira forcément. Si la condition de sortie n'est pas garantie, on risque une boucle infinie qui bloque le navigateur et le serveur.

Étape 10 - Ajouter un troisième personnage et organiser les combats

L'arène accueille un troisième combattant. Ajouter un personnage supplémentaire (par exemple "Miss Marple", 90 points de vie, 12 DPS).

Organiser trois combats :

  1. Le personnage 1 contre le personnage 2.
  2. Le vainqueur du premier combat contre le personnage 3.

Pour le deuxième combat, il faut connaître le vainqueur du premier. Modifier la fonction simulerCombat pour qu'elle renvoie les informations du vainqueur. Au lieu de simplement afficher le résultat, la fonction doit renvoyer un tableau contenant le nom, la vie restante et les DPS du vainqueur.

Rappel : en PHP, un tableau se déclare avec des crochets [valeur1, valeur2, valeur3]. On accède à ses éléments par leur position (en commençant à 0) : $tableau[0], $tableau[1], etc.


Bonne pratique - Renvoyer des résultats avec return

Quand une fonction doit renvoyer plusieurs valeurs, on utilise un tableau. C'est la manière standard en PHP. Cependant, on constate que manipuler un tableau avec des indices numériques ($vainqueur[0], $vainqueur[1]...) est peu lisible. On ne sait pas immédiatement ce que représente chaque indice. Ce problème sera résolu proprement à la séance 2 grâce aux classes, qui permettront de regrouper les données d'un personnage dans un objet nommé, avec des propriétés claires comme $personnage->getNom() ou $personnage->getVie().


Solution complète

Solution complète du TP

Exercices complémentaires

Ces exercices sont facultatifs. Ils permettent de s'entraîner davantage sur les notions vues dans cette séance.

Exercice A - Personnaliser l'affichage avec du CSS

Ajouter une balise <style> dans le <head> de index.php pour améliorer la présentation.

Quelques idées :

  • Changer la couleur de fond de la page.
  • Afficher les personnages dans des cadres (bordure, padding, marge).
  • Utiliser une couleur différente pour le message d'état selon qu'il est "en pleine forme", "blessé" ou "mort".

Cet exercice ne nécessite pas de PHP supplémentaire : il s'agit uniquement de CSS appliqué au HTML généré par PHP.

Exercice B - Ajouter un quatrième personnage

Ajouter un quatrième combattant et organiser un mini-tournoi :

  • Deux demi-finales (personnage 1 contre 2, personnage 3 contre 4).
  • Une finale entre les deux vainqueurs.

Exercice C - Simuler un combat à sens unique

Créer une variante de la fonction simulerCombat où le deuxième personnage ne riposte pas (il subit les attaques sans jamais attaquer). Combien de tours faut-il pour l'éliminer ?


Ce qu'il faut retenir

NotionRésumé
PHP côté serveurLe code PHP est exécuté sur le serveur. Le navigateur ne reçoit que du HTML.
VariablesElles commencent par $. PHP détermine le type automatiquement.
printAffiche du texte (y compris du HTML) dans la page.
ConcaténationLe point . assemble plusieurs chaînes de caractères.
if / else if / elseExécute un bloc de code différent selon une condition.
FonctionsBlocs de code réutilisables, définis avec function et appelés par leur nom.
returnRenvoie une valeur depuis une fonction vers le code appelant.
require_onceInclut un fichier PHP une seule fois, pour organiser le code en plusieurs fichiers.
whileRépète un bloc de code tant qu'une condition est vraie.

Aperçu de la prochaine séance

Les variables et les fonctions permettent de créer un jeu fonctionnel, mais on constate rapidement des limites : pour chaque personnage, il faut déclarer trois variables séparées ($nom1, $vie1, $dps1...), et les fonctions reçoivent de longues listes de paramètres.

La séance 2 introduira les classes : une manière de regrouper les données et les actions d'un personnage dans une seule entité. Au lieu de manipuler $nom1, $vie1, $dps1 séparément, on créera un objet $personnage1 qui contiendra toutes ces informations et saura lui-même comment attaquer, se présenter, etc.