PHP — le langage du serveur
Le premier langage qui tourne ailleurs que chez l'utilisateur — et c'est ce qui change tout.
Résumé flash
PHP s'exécute sur le serveur, avant que la page
ne parte vers le navigateur. Le visiteur ne reçoit jamais le code PHP : seulement son
résultat. Toute variable commence par $. On récupère les
données d'un formulaire avec $_POST / $_GET, on garde un
utilisateur connecté avec $_SESSION, et on factorise le code commun avec
include / require.
🔑
#côté-serveur #<?php #$variable #define
#isset #concaténation #foreach #include
#require #$_POST #$_GET #$_SESSION
#htmlspecialchars #fopen
01PHP s'exécute au serveur
C'est la idée à comprendre avant tout le reste. Le code PHP est interprété par le serveur, qui envoie ensuite au navigateur une page contenant uniquement du HTML. Le visiteur ne voit jamais votre code.
| PHP | JavaScript | |
|---|---|---|
| S'exécute | sur le serveur | dans le navigateur |
| Code visible par l'utilisateur | non, jamais | oui, entièrement |
| Peut accéder à | base de données, fichiers du serveur | la page affichée |
| Sert à | produire la page, traiter, sécuriser | rendre la page vivante |
Au chapitre JavaScript, on répétait : « la validation côté client ne sécurise rien ». La raison est ici. Le JavaScript est chez l'utilisateur, qui peut le lire, le modifier, le désactiver. PHP est sur votre machine, hors de sa portée. Toute donnée reçue doit être revérifiée en PHP, même si JavaScript l'a déjà contrôlée.
02Syntaxe et intégration
Le code PHP s'insère directement dans un fichier HTML (extension
.php), entre les balises <?php et ?>.
<!DOCTYPE html>
<html>
<head>
<title>Exemple PHP</title>
</head>
<body>
<h1>
<?php
echo "Bienvenue sur mon site !";
?>
</h1>
<p>Cette phrase est générée grâce à PHP.</p>
</body>
</html><h1>
Bienvenue sur mon site !
</h1>
<p>Cette phrase est générée grâce à PHP.</p>Faites l'expérience : « Afficher le code source de la page » dans le navigateur ne montrera
jamais le <?php>.
Les commentaires
// commentaire de ligne
# commentaire de ligne (autre écriture)
/* commentaire
sur plusieurs lignes */Ouvrir un .php en double-cliquant dessus affiche le code brut : aucun serveur ne
l'a interprété. Il faut XAMPP (ou équivalent) :
- démarrer Apache dans le panneau de contrôle XAMPP (il passe au vert) ;
- placer le fichier dans
C:\xampp\htdocs\; - l'ouvrir via
http://localhost/monprojet/index.php— jamais viafile:///C:/….
Si Apache refuse de démarrer, c'est presque toujours un conflit sur le port 80 (Skype, IIS, un autre serveur).
03Variables et constantes
Une variable PHP commence toujours par $. Pas besoin de la
déclarer : elle existe dès qu'on lui donne une valeur.
$nom = "Alice"; // chaîne de caractères
$age = 25; // entier
$taille = 1.70; // flottant
$estEtudiant = true; // booléen
$a = 10;
echo $a; // 10
$a = "bonjour"; // le TYPE peut changer en cours de route
echo $a; // bonjourRègles de nommage
- pas d'espace ;
- commence par une lettre ou un souligné
_; - ne doit pas être un mot-clé du langage.
Les constantes
define("PI", 3.14);
define("LANGUE", "Français");
echo PI; // 3.14 ← PAS de $ devant une constanteTester si une variable est utilisable
| Fonction | Renvoie true quand… |
|---|---|
isset($x) | la variable existe et n'est pas
null |
empty($x) | elle est vide : 0,
"0", "", null, false,
array() — ou n'existe pas |
empty() considère 0 comme videC'est le piège classique du formulaire. Un utilisateur saisit la quantité 0, parfaitement valable :
if (empty($_POST["quantite"])) {
echo "Quantité obligatoire"; // ✘ se déclenche aussi pour 0 !
}
if (!isset($_POST["quantite"]) || $_POST["quantite"] === "") {
echo "Quantité obligatoire"; // ✔ ne rejette que l'absence ou le vide réel
}La règle : isset() pour savoir si ça existe,
empty() seulement quand 0 doit effectivement compter comme vide.
04Les chaînes
PHP fait une différence essentielle entre guillemets doubles et simples.
$b = "ami";
$a = "bonjour $b"; // "bonjour ami" ← les variables sont INTERPRÉTÉES
$a = 'bonjour $b'; // "bonjour $b" ← elles ne le sont PASGuillemets simples ' ' → le texte est pris tel quel.
La concaténation : le point
$a = "bonjour ";
$b = "ami";
$c = $a . $b; // "bonjour ami"
echo "Le serveur " . $nom . " répond en " . $temps . " ms";., pas avec +C'est la confusion n° 1 quand on arrive de JavaScript :
| JavaScript | PHP | |
|---|---|---|
| Concaténer | "a" + "b" | "a" . "b" |
| Additionner | 2 + 3 | 2 + 3 |
En PHP, "2" + "3" vaut 5 : le + est
toujours une addition, il convertit le texte en nombre. Exactement l'inverse de
JavaScript. Bonne nouvelle : le piège du « 2 + 3 = 23 » n'existe pas ici.
05Conditions et boucles
La syntaxe est celle de JavaScript — accolades et parenthèses. Seules les variables changent d'allure.
if ($port === 443) {
echo "HTTPS";
} elseif ($port === 22) {
echo "SSH";
} else {
echo "Port inconnu";
}
switch ($jour) {
case 1: echo "Lundi"; break;
case 2: echo "Mardi"; break;
default: echo "Jour invalide";
}Quatre boucles
// while
$i = 0;
while ($i < 5) {
echo "i vaut $i<br>";
$i++;
}
// do … while : au moins un tour
$i = 0;
do {
echo "i vaut $i<br>";
$i++;
} while ($i < 5);
// for
for ($i = 0; $i < 5; $i++) {
echo "i vaut $i<br>";
}
// les trois affichent : i vaut 0 … i vaut 4foreach — la boucle des tableaux
$langages = ["C", "C++", "Java", "PHP"];
foreach ($langages as $langage) {
echo "Langage : $langage<br>";
}
// avec la clé, pour un tableau associatif
foreach ($services as $port => $nom) {
echo "Port $port : $nom<br>";
}foreach plutôt que for sur un tableauforeach est propre à PHP et n'a pas d'équivalent aussi simple dans le
pseudo-code. Son avantage : plus
d'indice à gérer, donc plus d'erreur d'un cran, et cela fonctionne aussi sur les
tableaux associatifs (dont les clés ne sont pas des nombres) — ce qu'un
for classique ne peut pas faire.
PHP produit du HTML : c'est donc <br> qui fait sauter une ligne à
l'écran, pas \n. Le \n n'apparaît que dans le code source de la
page — invisible pour le visiteur.
06Les fonctions
function nomFonction($param1, $param2) {
// code
return $valeur; // optionnel
}
function addition($a, $b) {
$somme = $a + $b;
return $somme;
}
$resultat = addition(5, 3);
echo $resultat; // 8
function direBonjour() { // sans paramètre
echo "Bonjour !";
}
direBonjour();echo dans une fonction et return :
attention au mélangeUne fonction qui affiche et retourne produit un affichage parasite :
function estPortSecurise($port) {
if ($port == 22 || $port == 443) {
echo "Le port est sécurisé.";
return true;
}
echo "Le port n'est pas sécurisé.";
return false;
}
echo estPortSecurise(443);
// Affiche : Le port est sécurisé.1
// ↑ echo true affiche « 1 »En PHP, echo true écrit 1 et
echo false n'écrit rien du tout. D'où ce « 1 » mystérieux.
La bonne pratique : une fonction calcule et retourne ; c'est l'appelant qui décide d'afficher.
function estPortSecurise($port) {
return ($port == 22 || $port == 443);
}
if (estPortSecurise(443)) {
echo "Le port est sécurisé.";
} else {
echo "Le port n'est pas sécurisé.";
}07include et require
Ils insèrent le contenu d'un autre fichier à l'endroit où ils sont écrits — la façon d'éviter de recopier l'en-tête et le pied de page sur chaque page du site.
<?php
echo "<h1>Bienvenue sur mon site !</h1>";
echo "<hr>";
?><?php
include 'header.php';
echo "<p>Contenu principal de la page</p>";
include 'footer.php';
?>La seule différence : que faire si le fichier manque
| Fichier absent | Pour quoi | |
|---|---|---|
include | warning, le script continue | fichiers facultatifs : header, footer, bannière |
require | erreur fatale, le script s'arrête | fichiers essentiels : configuration, connexion à la base, fonctions critiques |
Pour tout le reste, le comportement est identique.
Imaginez config.php (qui contient le mot de passe de la base) inclus avec
include. S'il disparaît, le script continue sans identifiants —
et enchaîne les erreurs, voire affiche des données qu'il ne devrait pas. Avec
require, tout s'arrête net.
Oui →
include · Non → require08Les formulaires
Quand un utilisateur remplit un formulaire, les données partent vers le serveur, où PHP les récupère.
<form method="post" action="traitement.php">
<input type="text" name="nom">
<input type="submit">
</form>method="post"— la méthode d'envoi ;action="traitement.php"— le fichier qui reçoit les données ;name="nom"— le nom de la variable envoyée.
<?php
$nom = $_POST["nom"]; // la clé "nom" = l'attribut name du champ
echo "Bonjour $nom";
?>GET ou POST ?
| Où vont les données | Visibles ? | Usage | |
|---|---|---|---|
| GET | dans l'URL | oui | afficher, rechercher, filtrer |
| POST | dans le corps de la requête HTTP | non | envoyer des données importantes |
site.com/traitement.php?nom=DupontLes superglobales
$_GET | données envoyées par l'URL |
$_POST | données envoyées par un formulaire en POST |
$_REQUEST | GET, POST ou cookie — indifféremment |
$_REQUEST est à éviterLe polycopié le présente comme l'une des « 3 principales ». En pratique, on ne l'utilise pas : puisqu'il mélange GET, POST et cookies, vous ne savez plus d'où vient la donnée. Un attaquant peut alors fournir par l'URL une valeur que vous croyiez recevoir d'un formulaire POST.
Soyez explicite : $_POST["nom"] si vous attendez un POST,
$_GET["page"] si vous attendez un paramètre d'URL. Le code dit alors ce qu'il
fait.
L'exemple du cours écrit echo "Bonjour $nom";. Si l'utilisateur saisit non pas
« Alice » mais du code HTML, celui-ci s'exécutera dans la page :
<script>alert("piraté")</script>C'est la faille XSS, vue au
chapitre
cybersécurité. Le cours mentionne htmlspecialchars() — c'est précisément la
parade, et elle doit devenir un réflexe systématique :
$nom = $_POST["nom"];
echo "Bonjour " . htmlspecialchars($nom);htmlspecialchars() transforme < en < :
le texte s'affiche, mais n'est plus interprété comme du code.
POST cache seulement les données de l'URL (donc de l'historique, des favoris et des journaux du serveur). Il ne les chiffre pas : elles circulent en clair comme le reste.
Ce qui chiffre, c'est HTTPS. Un mot de passe envoyé en POST sur du HTTP simple est aussi lisible qu'en GET — souvenez-vous de la démonstration Telnet dans Wireshark.
09Les sessions
HTTP ne se souvient de rien : chaque requête est indépendante. Les sessions permettent de conserver des informations sur un utilisateur pendant toute sa navigation — connexion, panier, préférences.
<?php
session_start(); // 1. démarrer — AVANT tout affichage
$_SESSION["user"] = "Paul"; // 2. enregistrer
echo $_SESSION["user"]; // 3. lire → Paul
session_destroy(); // 4. détruire (déconnexion)
?>session_start() doit venir avant le moindre affichagePas seulement avant un echo : avant tout caractère envoyé au
navigateur — y compris une simple ligne vide ou une espace avant le
<?php.
Warning: session_start(): Cannot send session cookie -
headers already sent by (output started at index.php:1)La cause est presque toujours une ligne blanche en tête de fichier. La session fonctionne grâce à un cookie, et un cookie voyage dans les en-têtes HTTP — qui partent avant le contenu. Une fois le contenu commencé, il est trop tard.
En arrivant, on vous remet un jeton numéroté (le cookie de session) et vos
affaires restent au vestiaire (sur le serveur, dans $_SESSION). À chaque
passage, vous montrez le jeton et l'on retrouve vos affaires.
L'important : vos affaires ne vous suivent pas. Le navigateur ne transporte que le numéro. C'est pourquoi une session est bien plus sûre qu'un cookie contenant directement les données.
10Les fichiers
PHP sait lire et écrire des fichiers sur le serveur : journaux d'événements, sauvegardes, exports CSV, envois de l'utilisateur.
Les modes d'ouverture
| Mode | Effet |
|---|---|
"r" | lecture seule, pointeur au début. Erreur si le fichier n'existe pas |
"w" | écriture seule. Crée le fichier, ou efface tout son contenu |
"a" | écriture à la fin : le contenu existant est conservé |
"r+" · "w+" · "a+" |
les mêmes, en lecture et écriture |
"x" | création exclusive : échoue si le fichier existe déjà |
$fichier = fopen("test.txt", "r");
echo fread($fichier, filesize("test.txt"));
fclose($fichier);
// ligne par ligne
$fichier = fopen("test.txt", "r");
while (!feof($fichier)) { // feof = End Of File
$ligne = fgets($fichier);
echo $ligne . "<br>";
}
fclose($fichier);$fichier = fopen("test.txt", "w"); // ⚠ efface le contenu existant
fwrite($fichier, "Bonjour");
fclose($fichier);
$fichier = fopen("test.txt", "a"); // ajoute à la fin
fwrite($fichier, "Nouvelle ligne\n");
fclose($fichier);"w" détruit le fichier sans prévenirOuvrir en "w" vide le fichier à l'instant même de l'ouverture,
avant toute écriture. Un journal d'événements ouvert par erreur en "w" au lieu
de "a" perd tout son historique — silencieusement.
"a" · Repartir de zéro →
"w"Et toujours fclose() : cela libère la ressource et garantit que
tout est bien écrit sur le disque.
Ce script devait enregistrer chaque connexion dans un journal. Après une semaine, le fichier ne contient qu'une seule ligne. Pourquoi ?
$f = fopen("connexions.log", "w");
fwrite($f, date("d/m/Y H:i") . " — " . $_SESSION["user"] . "\n");
fclose($f);Le mode "w" vide le fichier à chaque
ouverture. Chaque connexion efface donc les précédentes : il ne reste que la
dernière.
$f = fopen("connexions.log", "a"); // ← ajout à la fin
fwrite($f, date("d/m/Y H:i") . " — " . $_SESSION["user"] . "\n");
fclose($f);Un seul caractère de différence, et un historique entier sauvé. C'est le genre de détail qui distingue un script qui « marche » d'un script juste.