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

Sessions PHP — exercices

Le TP3 entier, du premier formulaire à l'espace membre protégé — et les trois pannes que tout le monde rencontre.

🎯

Le réflexe de débogage

Quand une session « ne marche pas », affichez-la : echo "<pre>"; print_r($_SESSION); echo "</pre>";. Vous verrez immédiatement si elle est vide (oubli de session_start()) ou si la clé est mal orthographiée.

01POST puis GET (TP3 · ex. 1)

1Le même formulaire, deux méthodes Facile

Créer un formulaire avec nom et prénom, l'envoyer en POST et afficher « Bonjour NOM PRÉNOM ». Refaire la même chose en GET, puis comparer $_GET et $_POST.

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

    <label for="prenom">Prénom :</label>
    <input type="text" id="prenom" name="prenom">

    <input type="submit" value="Envoyer">
</form>
php — traitement.php
<?php
if ($_SERVER["REQUEST_METHOD"] === "POST") {

    if (!empty($_POST["nom"]) && !empty($_POST["prenom"])) {
        $nom    = htmlspecialchars(trim($_POST["nom"]));
        $prenom = htmlspecialchars(trim($_POST["prenom"]));
        echo "Bonjour $nom $prenom";
    } else {
        echo "Merci de remplir les deux champs.";
    }
}
?>

Pour la version GET, deux changements seulement :

les différences
method="post"   →   method="get"
$_POST["nom"]   →   $_GET["nom"]

Et l'URL devient visible :

navigateur
traitement.php?nom=Dupont&prenom=Marc
🧰 Ce que la comparaison doit faire dire
ConstatConséquence
En GET, les données sont dans l'URL on peut partager le lien — pratique pour une recherche
L'URL reste dans l'historique jamais de mot de passe en GET
On peut modifier l'URL à la main il faut toujours revalider côté serveur
En POST, rafraîchir renvoie le formulaire le navigateur demande confirmation

02Valider email et mot de passe (TP3 · ex. 2)

2Des messages d'erreur utiles Moyen

Formulaire avec email et mot de passe. Vérifier que l'email n'est pas vide et que le mot de passe fait au moins 6 caractères. Afficher les erreurs, ou « Connexion réussie ».

✅ Correction
php
<?php
$erreurs = [];

if ($_SERVER["REQUEST_METHOD"] === "POST") {

    $email = trim($_POST["email"] ?? "");
    $mdp   = $_POST["password"] ?? "";       // pas de trim sur un mot de passe

    if ($email === "") {
        $erreurs[] = "L'email est obligatoire.";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $erreurs[] = "Le format de l'email est invalide.";
    }

    if (strlen($mdp) < 6) {
        $erreurs[] = "Le mot de passe doit faire au moins 6 caractères.";
    }

    if (count($erreurs) === 0) {
        echo "<p style='color:green'>Connexion réussie</p>";
    } else {
        foreach ($erreurs as $e) {
            echo "<p style='color:red'>" . htmlspecialchars($e) . "</p>";
        }
    }
}
?>
🧰 elseif plutôt qu'un second if

Si l'email est vide, inutile de tester en plus son format : on afficherait deux messages pour un seul problème. Le elseif enchaîne les contrôles du plus grossier au plus fin — on ne signale que l'erreur la plus pertinente.

En revanche le mot de passe a son if indépendant : c'est un autre champ, et l'utilisateur doit voir ses deux erreurs d'un coup.

⚠️ type="email" en HTML ne suffit pas

L'attribut HTML fait une première vérification dans le navigateur — c'est du confort. Mais il se désactive en deux clics dans les outils développeur, et une requête peut être envoyée sans passer par la page.

filter_var(…, FILTER_VALIDATE_EMAIL) refait le contrôle côté serveur, là où l'utilisateur n'a pas la main. Les deux sont complémentaires : jamais l'un à la place de l'autre.

03Compteur de visites (TP3 · étape 2)

3La première mémoire Facile

À chaque chargement de la page, incrémenter $_SESSION['visites'] et afficher « Vous avez visité cette page X fois ».

✅ Correction
php
<?php
session_start();

if (!isset($_SESSION["visites"])) {
    $_SESSION["visites"] = 1;
} else {
    $_SESSION["visites"]++;
}

echo "Vous avez visité cette page " . $_SESSION["visites"] . " fois.";
?>

Ou, en une ligne :

php
$_SESSION["visites"] = ($_SESSION["visites"] ?? 0) + 1;
⚠️ Le compteur remonte à 1 tout seul ?

Trois causes possibles, dans l'ordre de fréquence :

  1. session_start() oublié sur cette page-là ;
  2. le navigateur refuse les cookies — sans cookie, pas de jeton, donc une nouvelle session à chaque requête ;
  3. session_destroy() appelé quelque part par erreur.

04L'espace membre complet (TP3 · ex. 3)

4Quatre fichiers qui se répondent Exigeant

Assembler l'espace membre : connexion (admin / 1234), page privée protégée, compteur de visites et déconnexion.

✅ Correction complète
php — login.php (PAS de garde)
<?php
session_start();
$erreur = "";

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $login = trim($_POST["login"] ?? "");
    $mdp   = $_POST["password"] ?? "";

    if (strtolower($login) === "admin" && $mdp === "1234") {
        $_SESSION["user"] = $login;
        header("Location: accueil.php");
        exit();
    }
    $erreur = "Identifiants incorrects";
}
?>
<!DOCTYPE html>
<html lang="fr">
<head><meta charset="utf-8"><title>Connexion</title></head>
<body>
    <h1>Connexion</h1>

    <?php if ($erreur !== ""): ?>
        <p style="color:red"><?php echo htmlspecialchars($erreur); ?></p>
    <?php endif; ?>

    <form method="post" action="login.php">
        <label for="login">Identifiant :</label>
        <input type="text" id="login" name="login" required>

        <label for="password">Mot de passe :</label>
        <input type="password" id="password" name="password" required>

        <input type="submit" value="Se connecter">
    </form>
</body>
</html>
php — accueil.php (page privée, AVEC garde)
<?php
session_start();

if (!isset($_SESSION["user"])) {        // le garde
    header("Location: login.php");
    exit();
}

$_SESSION["visites"] = ($_SESSION["visites"] ?? 0) + 1;
$user = htmlspecialchars($_SESSION["user"]);
?>
<!DOCTYPE html>
<html lang="fr">
<head><meta charset="utf-8"><title>Espace membre</title></head>
<body>
    <h1>Bonjour <?php echo $user; ?> !</h1>
    <p>Vous avez visité cette page <?php echo $_SESSION["visites"]; ?> fois.</p>
    <p><a href="logout.php">Déconnexion</a></p>
</body>
</html>
php — logout.php
<?php
session_start();
$_SESSION = [];
session_destroy();
header("Location: login.php");
exit();
?>
🧰 Pourquoi login.php se poste à lui-même

action="login.php" sur la page login.php : ce n'est pas une erreur, c'est le motif classique. La page joue deux rôles selon la méthode :

  • arrivée normale (GET) → elle affiche le formulaire ;
  • envoi du formulaire (POST) → elle traite, puis redirige.

L'avantage décisif : en cas d'erreur, on réaffiche le formulaire avec le message, sans page intermédiaire. Avec un traitement.php séparé, l'utilisateur se retrouve sur une page nue affichant « Identifiants incorrects », et doit revenir en arrière.

⚠️ La syntaxe <?php if (…): ?> … <?php endif; ?>

Cette écriture alternative évite d'empiler des echo contenant du HTML échappé. Elle est bien plus lisible dès qu'on mélange les deux langages — et c'est la forme attendue dans un fichier de vue.

05Trois pannes à diagnostiquer

5Symptôme, cause, remède Exigeant

Pour chaque symptôme, donnez la cause et la correction.

  1. Le navigateur affiche ERR_TOO_MANY_REDIRECTS sur la page de connexion.
  2. Warning: session_start(): Cannot send session cookie - headers already sent.
  3. L'utilisateur se connecte, arrive sur l'accueil, mais en cliquant vers profil.php il est renvoyé au login.
✅ Correction
#CauseCorrection
1 Le garde est sur login.php : un visiteur non connecté y est redirigé… vers login.php, indéfiniment retirer le garde de la page de connexion — il ne va que sur les pages privées
2 Quelque chose a été envoyé avant session_start() : un echo, du HTML, ou une simple ligne vide avant <?php mettre <?php session_start(); au tout début, sans rien devant — pas même une espace
3 session_start() manque dans profil.php : pour cette page, $_SESSION est vide, donc le garde conclut « non connecté » ajouter session_start() en première ligne de chaque page
🧰 Le diagnostic en trois secondes
php — à coller temporairement
echo "<pre>";
print_r($_SESSION);
echo "</pre>";
Ce que vous voyezCe que ça signifie
Array ( ) — vide session_start() manquant, ou session détruite
Les données sont là, mais le garde refuse la clé est mal orthographiée : $_SESSION["users"] au lieu de ["user"]
Rien ne s'affiche du touterreur fatale plus haut — regardez les logs d'Apache

Pensez à retirer ces lignes avant de rendre : elles affichent le contenu de la session à qui visite la page.

⚡ Les erreurs qui coûtent le plus de points

  • Le garde sur login.php → boucle de redirection infinie.
  • session_start() oublié sur une des pages.
  • Quoi que ce soit avant session_start() — même une ligne vide.
  • exit() oublié après header("Location: …") : le code continue et peut divulguer la page privée.
  • trim() appliqué au mot de passe.
  • Afficher $_SESSION["user"] sans htmlspecialchars().
  • Faute de frappe dans un nom de fichier inclus — include ne fait qu'un warning.

Sources exploitées

  • TP3 — Formulaires, validation et espace membre (le professeur)
  • Fichiers rendus — l'élève : login.php, traitement.php, accueil.php, session.php, session2.php