Accueil/Informatique & Développement /Chapitre 05 /Exercices corrigés

PHP — exercices

Du premier echo au mini-projet complet — avec le « 1 » mystérieux qui apparaît quand on mélange echo et return.

🎯

Avant de commencer

Apache démarré dans XAMPP, fichier dans htdocs, et l'on ouvre http://localhost/… — jamais file:///. Si vous voyez votre code PHP s'afficher dans le navigateur, c'est ce point-là qui cloche.

01Premier script (TP1 · ex. 1)

1Vérifier que PHP fonctionne Facile

Démarrer Apache, créer un fichier dans htdocs et afficher un message.

✅ Correction
php — C:\xampp\htdocs\test.php
<?php
echo "Bonjour ! PHP fonctionne.";
?>
dans le navigateur
http://localhost/test.php
⚠️ Les trois pannes du premier jour
SymptômeCause
Le code PHP s'affiche en toutes lettres fichier ouvert en file:/// — aucun serveur ne l'interprète
Apache ne démarre pas (reste rouge) conflit sur le port 80 — Skype, IIS, un autre serveur
Erreur 404 le fichier n'est pas dans htdocs, ou le nom est mal orthographié

02Jour de la semaine (TP1 · ex. 2)

2Un switch complet Facile

Créer une variable $jour (1 à 7) et afficher le nom du jour correspondant (1 = Lundi … 7 = Dimanche). Ajouter un default pour les valeurs invalides.

✅ Correction
php
<?php
$jour = 3;

switch ($jour) {
    case 1: echo "Lundi";    break;
    case 2: echo "Mardi";    break;
    case 3: echo "Mercredi"; break;
    case 4: echo "Jeudi";    break;
    case 5: echo "Vendredi"; break;
    case 6: echo "Samedi";   break;
    case 7: echo "Dimanche"; break;
    default: echo "Jour invalide";
}
?>
résultat
Mercredi
⚠️ Retirez un break et tout déraille

Sans break après case 3, l'exécution continue dans les cas suivants. Avec $jour = 3, on obtiendrait :

sortie fautive
MercrediJeudiVendrediSamediDimancheJour invalide

Le default lui-même s'exécute. C'est un excellent moyen de vérifier que vous avez compris : essayez, vous ne l'oublierez plus.

🧰 La version tableau, bien plus courte
php
$jours = [1 => "Lundi", "Mardi", "Mercredi", "Jeudi",
               "Vendredi", "Samedi", "Dimanche"];

echo $jours[$jour] ?? "Jour invalide";

Le 1 => impose de commencer les clés à 1 ; les suivantes suivent automatiquement. L'opérateur ?? fournit une valeur de repli si la clé n'existe pas. L'exercice demande un switch — mais sachez que cette écriture existe.

03Scan de ports (TP1 · ex. 3)

3Boucle et correspondance Moyen

Afficher les ports 20 à 25 sous la forme « Scan du port 20 », en indiquant à côté le service connu :

PortService
21FTP
22SSH
23Telnet
25SMTP
✅ Correction
php
<?php
$services = [
    21 => "FTP",
    22 => "SSH",
    23 => "Telnet",
    25 => "SMTP"
];

for ($port = 20; $port <= 25; $port++) {
    echo "Scan du port $port";

    if (isset($services[$port])) {
        echo " — " . $services[$port];
    } else {
        echo " — service inconnu";
    }
    echo "<br>";
}
?>
résultat
Scan du port 20 — service inconnu
Scan du port 21 — FTP
Scan du port 22 — SSH
Scan du port 23 — Telnet
Scan du port 24 — service inconnu
Scan du port 25 — SMTP
🧰 Le tableau associatif, plus malin que six if

On aurait pu écrire quatre if en cascade. Le tableau associatif (clé → valeur) est préférable : la table des services devient une donnée, pas du code. Pour ajouter le port 80, on ajoute une ligne au tableau — sans toucher à la boucle.

isset($services[$port]) répond à « cette clé existe-t-elle ? » et gère proprement les ports 20 et 24, absents de la table.

🌍 Ces quatre ports, vous les connaissez déjà

FTP (21), SSH (22), Telnet (23), SMTP (25) : ce sont ceux du modèle OSI. Et souvenez-vous de la démonstration Wireshark : Telnet (23) fait circuler les mots de passe en clair, contrairement à SSH (22). Un « scan de ports » qui trouve le 23 ouvert, c'est un signalement de sécurité.

04Fonctions réseau (TP1 · ex. 4 et 5)

4Bande passante et port sécurisé Moyen

  1. Écrire une fonction qui calcule une bande passante à partir d'une taille et d'un temps.
  2. Écrire une fonction estPortSecurise($port) qui retourne vrai pour les ports 22 et 443.
✅ Correction
php
<?php
function calculBandePassante($taille, $temps) {
    return $taille / $temps;
}

echo calculBandePassante(1024, 5);      // 204.8
?>
⚠️ Le « 1 » mystérieux à la fin de l'affichage

Une écriture fréquente de la seconde fonction produit une sortie étrange :

php — ce qui a été rendu
function estPortSecurise($port) {
    if ($port == 22 || $port == 443) {
        echo "Le port est sécurisé.";
        return true;
    } else {
        echo "Le port n'est pas sécurisé.";
        return false;
    }
};

echo estPortSecurise(443);
sortie réelle
Le port est sécurisé.1
                     ↑ d'où sort ce 1 ?

La fonction affiche le message et retourne true. Le echo de l'appel affiche donc, en plus, la valeur retournée — et en PHP echo true écrit 1 (tandis que echo false n'écrit rien).

Au passage : le ; après l'accolade fermante de la fonction est inutile.

🧰 La version propre : calculer d'un côté, afficher de l'autre
php
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é.";
}

La fonction devient réutilisable : on peut s'en servir dans un if, dans un tableau, dans une autre fonction — sans qu'elle impose son affichage. C'est le même principe qu'en JavaScript : afficher est pour l'humain, retourner est pour le programme.

05Tableau de bord réseau (TP2)

5Mini-projet complet Exigeant

Construire un tableau de bord réseau réparti en plusieurs fichiers :

  1. header.php — le titre du tableau de bord ;
  2. footer.php — une ligne de séparation et un texte d'administration ;
  3. fonctions_reseau.php — une fonction « le port est-il sécurisé ? » et une fonction « quel service pour ce port ? » ;
  4. index.php — un tableau de serveurs (nom, IP, port), les inclusions, et un tableau HTML affichant nom, IP, port, service et sécurité, parcouru avec foreach.
✅ Correction
php — header.php
<?php
echo "<h1>Tableau de bord du réseau</h1>";
echo "<hr>";
?>
php — footer.php
<?php
echo "<hr>";
echo "<p>Administration réseau © 2026</p>";
?>
php — fonctions_reseau.php
<?php
function estPortSecurise($port) {
    return ($port == 22 || $port == 443);
}

function nomDuService($port) {
    $services = [
        21  => "FTP",
        22  => "SSH",
        23  => "Telnet",
        25  => "SMTP",
        80  => "HTTP",
        443 => "HTTPS"
    ];
    return $services[$port] ?? "Inconnu";
}
?>
php — index.php
<?php
require 'fonctions_reseau.php';   // ← require : le site n'a aucun sens sans
include 'header.php';

$serveurs = [
    ["nom" => "SRV-WEB",  "ip" => "192.168.0.10", "port" => 443],
    ["nom" => "SRV-FILE", "ip" => "192.168.0.11", "port" => 21],
    ["nom" => "SRV-ADM",  "ip" => "192.168.0.12", "port" => 22],
    ["nom" => "SRV-OLD",  "ip" => "192.168.0.13", "port" => 23]
];

echo "<table border='1'>";
echo "<tr><th>Serveur</th><th>IP</th><th>Port</th>"
   . "<th>Service</th><th>Sécurisé</th></tr>";

foreach ($serveurs as $s) {
    $securise = estPortSecurise($s["port"]) ? "Oui" : "Non";

    echo "<tr>";
    echo "<td>" . htmlspecialchars($s["nom"]) . "</td>";
    echo "<td>" . htmlspecialchars($s["ip"])  . "</td>";
    echo "<td>" . $s["port"] . "</td>";
    echo "<td>" . nomDuService($s["port"]) . "</td>";
    echo "<td>" . $securise . "</td>";
    echo "</tr>";
}
echo "</table>";

include 'footer.php';
?>
résultat
Serveur    IP              Port   Service   Sécurisé
SRV-WEB    192.168.0.10    443    HTTPS     Oui
SRV-FILE   192.168.0.11    21     FTP       Non
SRV-ADM    192.168.0.12    22     SSH       Oui
SRV-OLD    192.168.0.13    23     Telnet    Non
🧰 Les trois choix qui font la note
  • require pour les fonctions, include pour le header : sans les fonctions, la page n'a aucun sens — il faut qu'elle s'arrête. Sans le header, elle reste lisible.
  • L'opérateur ?? dans nomDuService : il évite un avertissement « clé indéfinie » pour un port inconnu.
  • L'écriture ternaire condition ? "Oui" : "Non" : un if…else en une ligne, très courant en PHP.
🌍 Ce que raconte ce tableau de bord

Deux serveurs sur quatre ne sont pas sécurisés : SRV-FILE en FTP et SRV-OLD en Telnet. Ce sont exactement les protocoles qui font circuler les identifiants en clair. Un vrai tableau de bord d'administrateur sert précisément à faire ressortir cela d'un coup d'œil — et à déclencher la migration vers SFTP et SSH.

06Traiter un formulaire

6Recevoir, vérifier, afficher Moyen

Créer un formulaire demandant un nom et une adresse IP, puis un traitement.php qui vérifie que les deux champs sont remplis, que l'IP est valide, et affiche un message — sans faille d'affichage.

✅ Correction
html — formulaire.html
<form method="post" action="traitement.php">
    <label for="nom">Nom du poste :</label>
    <input type="text" id="nom" name="nom">

    <label for="ip">Adresse IP :</label>
    <input type="text" id="ip" name="ip">

    <input type="submit" value="Enregistrer">
</form>
php — traitement.php
<?php
$erreurs = [];

if (!isset($_POST["nom"]) || trim($_POST["nom"]) === "") {
    $erreurs[] = "Le nom est obligatoire.";
}

if (!isset($_POST["ip"]) || filter_var($_POST["ip"], FILTER_VALIDATE_IP) === false) {
    $erreurs[] = "L'adresse IP est invalide.";
}

if (count($erreurs) > 0) {
    foreach ($erreurs as $e) {
        echo "<p style='color:red'>" . htmlspecialchars($e) . "</p>";
    }
} else {
    $nom = htmlspecialchars(trim($_POST["nom"]));
    $ip  = htmlspecialchars($_POST["ip"]);
    echo "<p>Poste <strong>$nom</strong> enregistré à l'adresse $ip.</p>";
}
?>
🧰 filter_var vaut mieux qu'une expression régulière

Pour valider une IP, on pourrait écrire une regex — longue, et facile à rater (elle doit refuser 999.1.1.1). PHP fournit le contrôle tout fait :

php
filter_var($ip, FILTER_VALIDATE_IP)        // adresse IP
filter_var($mail, FILTER_VALIDATE_EMAIL)   // adresse e-mail

Ces filtres sont écrits et testés par les développeurs de PHP : ils seront toujours plus fiables qu'une regex improvisée.

⚠️ Les trois réflexes de tout traitement de formulaire
  1. isset() avant de lire : un champ absent (formulaire trafiqué, ou appel direct de traitement.php) provoquerait un avertissement.
  2. trim() : sinon un champ ne contenant qu'une espace passe pour rempli.
  3. htmlspecialchars() avant d'afficher : la parade contre l'injection de code (XSS).

Et rappelez-vous : même si JavaScript a déjà tout vérifié côté client, PHP doit tout revérifier. Le client, on ne le contrôle pas.

⚡ Les erreurs qui coûtent le plus de points

  • Ouvrir le fichier en file:/// au lieu de http://localhost/.
  • Oublier le $ devant une variable — ou en mettre un devant une constante.
  • Concaténer avec + au lieu de .
  • Oublier un break dans un switch.
  • Mélanger echo et return dans une fonction → le « 1 » parasite.
  • include là où il fallait require.
  • Afficher une donnée utilisateur sans htmlspecialchars().
  • session_start() après un affichage → headers already sent.

Sources exploitées

  • TP1 — Structures, boucles, fonctions et inclusions (le professeur)
  • TP2 — Mini-projet « Tableau de bord réseau »
  • Comptes rendus et fichiers rendus — l'élève (tp1ex4, tp1ex5, fonctions_reseau.php)