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.

SERVEUR Apache + PHP <?php … ?> exécute le code, produit du HTML NAVIGATEUR HTML + CSS + JS <h1>Bonjour</h1> ne reçoit QUE le résultat HTML produit → ← requête HTTP Le code PHP ne franchit jamais cette flèche.
PHP tourne à gauche, JavaScript à droite. C'est toute la différence entre les deux langages.
PHPJavaScript
S'exécutesur le serveur dans le navigateur
Code visible par l'utilisateurnon, 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
🌍 C'est pourquoi la sécurité est côté serveur

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 ?>.

php
<!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>
ce que reçoit le navigateur
<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

php
// commentaire de ligne
#  commentaire de ligne (autre écriture)
/* commentaire
   sur plusieurs lignes */
⚠️ Il faut un serveur — le double-clic ne suffit pas

Ouvrir un .php en double-cliquant dessus affiche le code brut : aucun serveur ne l'a interprété. Il faut XAMPP (ou équivalent) :

  1. démarrer Apache dans le panneau de contrôle XAMPP (il passe au vert) ;
  2. placer le fichier dans C:\xampp\htdocs\ ;
  3. l'ouvrir via http://localhost/monprojet/index.php — jamais via file:///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.

php
$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;                   // bonjour

Règles de nommage

  • pas d'espace ;
  • commence par une lettre ou un souligné _ ;
  • ne doit pas être un mot-clé du langage.

Les constantes

php
define("PI", 3.14);
define("LANGUE", "Français");

echo PI;        // 3.14   ← PAS de $ devant une constante

Tester si une variable est utilisable

FonctionRenvoie 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 vide

C'est le piège classique du formulaire. Un utilisateur saisit la quantité 0, parfaitement valable :

php
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.

php
$b = "ami";

$a = "bonjour $b";      // "bonjour ami"     ← les variables sont INTERPRÉTÉES
$a = 'bonjour $b';      // "bonjour $b"      ← elles ne le sont PAS
Guillemets doubles " " → les variables sont remplacées.
Guillemets simples ' ' → le texte est pris tel quel.

La concaténation : le point

php
$a = "bonjour ";
$b = "ami";
$c = $a . $b;           // "bonjour ami"

echo "Le serveur " . $nom . " répond en " . $temps . " ms";
⚠️ En PHP on concatène avec ., pas avec +

C'est la confusion n° 1 quand on arrive de JavaScript :

JavaScriptPHP
Concaténer"a" + "b""a" . "b"
Additionner2 + 32 + 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.

php
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

php
// 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 4

foreach — la boucle des tableaux

php
$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 tableau

foreach 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.

⚠️ Les retours à la ligne s'écrivent en HTML

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

php
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élange

Une fonction qui affiche et retourne produit un affichage parasite :

php
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.

php — propre
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 — header.php
<?php
echo "<h1>Bienvenue sur mon site !</h1>";
echo "<hr>";
?>
php — index.php
<?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 absentPour quoi
includewarning, le script continue fichiers facultatifs : header, footer, bannière
requireerreur fatale, le script s'arrête fichiers essentiels : configuration, connexion à la base, fonctions critiques

Pour tout le reste, le comportement est identique.

🧰 Bien choisir, c'est se protéger

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.

Le site peut-il fonctionner sans ce fichier ?
Oui → include · Non → require

08Les formulaires

Quand un utilisateur remplit un formulaire, les données partent vers le serveur, où PHP les récupère.

html — formulaire.html
<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 — traitement.php
<?php
$nom = $_POST["nom"];        // la clé "nom" = l'attribut name du champ
echo "Bonjour $nom";
?>

GET ou POST ?

Où vont les donnéesVisibles ?Usage
GETdans l'URLoui afficher, rechercher, filtrer
POSTdans le corps de la requête HTTP nonenvoyer des données importantes
avec GET, tout se voit
site.com/traitement.php?nom=Dupont

Les superglobales

$_GETdonnées envoyées par l'URL
$_POSTdonnées envoyées par un formulaire en POST
$_REQUESTGET, POST ou cookie — indifféremment
🔧 Corrigé — $_REQUEST est à éviter

Le 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.

🔧 Corrigé — n'affichez jamais une donnée utilisateur telle quelle

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 :

ce que l'utilisateur peut saisir
<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 :

php — correct
$nom = $_POST["nom"];
echo "Bonjour " . htmlspecialchars($nom);

htmlspecialchars() transforme < en &lt; : le texte s'affiche, mais n'est plus interprété comme du code.

⚠️ « POST est plus sécurisé » — à nuancer

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
<?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 affichage

Pas seulement avant un echo : avant tout caractère envoyé au navigateur — y compris une simple ligne vide ou une espace avant le <?php.

console
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.

💡 Le vestiaire

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

ModeEffet
"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à
php — lire
$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);
php — écrire
$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évenir

Ouvrir 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.

Ajouter à un journal → "a" · Repartir de zéro → "w"

Et toujours fclose() : cela libère la ressource et garantit que tout est bien écrit sur le disque.

🧠 Auto-évaluation

Ce script devait enregistrer chaque connexion dans un journal. Après une semaine, le fichier ne contient qu'une seule ligne. Pourquoi ?

php
$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.

php — corrigé
$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.

⚡ Récap 2 minutes

  • PHP s'exécute au serveur : l'utilisateur ne reçoit que le HTML produit. D'où : la sécurité se fait ici.
  • Syntaxe : <?php … ?>, variables en $, constantes par define() (sans $).
  • Chaînes : "$var" interprète, '$var' non. Concaténation avec ., pas +.
  • Tests : isset() pour l'existence, empty() avec prudence (0 y est « vide »).
  • Boucles : while, do…while, for, et surtout foreach pour les tableaux.
  • Inclusion : include (facultatif) · require (indispensable, arrête tout).
  • Formulaires : $_POST / $_GET selon la méthode ; la clé est l'attribut name. $_REQUEST : à éviter.
  • Toujours htmlspecialchars() avant d'afficher une donnée utilisateur.
  • Sessions : session_start() en toute première ligne, $_SESSION, session_destroy().
  • Fichiers : "a" ajoute, "w" écrase. Toujours fclose().

Sources exploitées

  • Cours « PHP — Développement côté serveur » (le professeur, BTS CIEL 2025-2026)
  • TP1 — Structures, boucles, fonctions et inclusions · TP2 — Tableau de bord réseau
  • comptes rendus d'élève (TP1, TP2)