• 8 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

Paperback available in this course

course.header.alt.is_certifying

Got it!

Last updated on 9/30/24

Conservez des données grâce aux sessions et aux cookies

Dans le chapitre précédent, vous avez mis en place un système de connexion. Il fonctionne certes, mais il ne conserve pas l'information !

Dans ce chapitre, vous allez apprendre à manipuler deux notions qui permettent de conserver l'information entre deux pages PHP pour une durée plus ou moins longue. Bienvenue dans le monde des données persistantes, un sujet qui va nous occuper jusqu'à la fin de ce cours !

À la fin de ce chapitre, vous disposerez d'un système de connexion entièrement fonctionnel.

Conservez les données grâce aux sessions

Jusqu'ici, nous étions parvenus à passer des variables de page en page à l'aide d'URL ou de formulaires. On sait ainsi envoyer d'une page à une autre le nom et le prénom du visiteur. Mais dès qu'on charge une autre page, ces informations sont « oubliées ». C'est pour cela qu'on a inventé les sessions.

Comprenez le fonctionnement des sessions

Comment sont gérées les sessions en PHP ?

Voici les trois étapes à connaître :

Étape 1 : création d'une session unique
  1. Un visiteur arrive sur votre site.

  2. On demande à créer une session pour lui.

  3. PHP génère alors un numéro unique.

Ce numéro est souvent très grand. Exemple : a02bbffc6198e6e0cc2715047bc3766f.

Étape 2 : création de variables pour la session

Une fois la session générée, on peut créer une infinité de variables de session pour nos besoins.

Par exemple, on peut créer :

  • une variable qui contient le nom du visiteur : $_SESSION['nom'] 

  • une autre qui contient son prénom : $_SESSION['prenom'] 

  • etc.

Étape 3 : suppression de la session

Lorsque le visiteur se déconnecte de votre site, la session est fermée et PHP « oublie » alors toutes les variables de session que vous avez créées.

Il est en fait difficile de savoir précisément quand un visiteur quitte votre site. En effet, lorsqu'il ferme son navigateur ou va sur un autre site, le vôtre n'en est pas informé.

Soit le visiteur clique sur un bouton « Déconnexion » (que vous aurez créé) avant de s'en aller, soit on attend quelques minutes d'inactivité pour le déconnecter automatiquement : on parle alors de "timeout". Le plus souvent, le visiteur est déconnecté par un timeout.

Pour activer ou détruire une session, deux fonctions sont à connaître :

  1.  session_start() : démarre le système de sessions. Si le visiteur vient d'arriver sur le site, alors un numéro de session est généré pour lui. 

  2.  session_destroy() : ferme la session du visiteur. Cette fonction est automatiquement appelée lorsque le visiteur ne charge plus de page de votre site pendant plusieurs minutes (c'est le timeout), mais vous pouvez aussi créer une page « Déconnexion » si le visiteur souhaite se déconnecter manuellement.

Mettez en place une session

Je vous propose d'étudier un exemple concret pour que vous voyiez à quel point c'est simple à utiliser, en mettant en place une session pour conserver l'information sur l'utilisateur connecté après connexion :

Concrètement, les sessions peuvent servir dans de nombreux cas sur votre site (et pas seulement pour retenir un nom et un prénom !).

Voici quelques exemples :

  • Imaginez un script qui demande un identifiant et un mot de passe pour qu'un visiteur puisse se « connecter » (s'authentifier). On peut enregistrer ces informations dans des variables de session et se souvenir de l'identifiant du visiteur sur toutes les pages du site !

  • Puisqu'on retient son identifiant et que la variable de session n'est créée que s'il a réussi à s'authentifier, on peut l'utiliser pour restreindre certaines pages de notre site à certains visiteurs uniquement. Cela permet de créer toute une zone d'administration sécurisée : si la variable de session login existe, on affiche le contenu, sinon on affiche une erreur. Cela devrait vous rappeler l'exercice sur la protection d'une page par mot de passe, sauf qu'ici, on peut se servir des sessions pour protéger automatiquement plusieurs pages.

  • On se sert activement des sessions sur les sites de vente en ligne. Cela permet de gérer un « panier » : on retient les produits que commande le client quelle que soit la page où il est. Lorsqu'il valide sa commande, on récupère ces informations et… on le fait payer. 

Apportons des modifications à notre projet

Nous allons effectuer plusieurs ajustements sur notre projet afin de le préparer pour la suite de ce cours.

1. Affichons les recettes même si l'utilisateur n'est pas connecté.

Dans le chapitre précédent, nous avions limité l'affichage des recettes aux utilisateurs connectés pour que vous ayez des bases solides pour la suite. Cependant, dans la vraie vie, nous souhaitons que nos recettes soient visibles par tous. Par conséquent, nous allons afficher à nouveau nos recettes. Modifions index.php :

<!-- inclusion des variables et fonctions -->

<?php
session_start();
require_once(__DIR__ . '/variables.php');
require_once(__DIR__ . '/functions.php');
?>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Site de recettes - Page d'accueil</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>

<body class="d-flex flex-column min-vh-100">
    <div class="container">
        <!-- inclusion de l'entête du site -->
        <?php require_once(__DIR__ . '/header.php'); ?>
        <h1>Site de recettes</h1>

        <!-- Formulaire de connexion -->
        <?php require_once(__DIR__ . '/login.php'); ?>

        <?php foreach (getRecipes($recipes) as $recipe) : ?>
            <article>
                <h3><?php echo $recipe['title']; ?></h3>
                <div><?php echo $recipe['recipe']; ?></div>
                <i><?php echo displayAuthor($recipe['author'], $users); ?></i>
            </article>
        <?php endforeach ?>
    </div>

    <!-- inclusion du bas de page du site -->
    <?php require_once(__DIR__ . '/footer.php'); ?>
</body>
</html>

2. Séparons notre fichier login.php en deux fichiers, tout comme nous l'avons fait pour le formulaire de contact.

Dans le fichier login.php, nous allons afficher notre formulaire de connexion :

<!--
   Si utilisateur/trice est non identifié(e), on affiche le formulaire
-->

<?php if (!isset($_SESSION['LOGGED_USER'])) : ?>
    <form action="submit_login.php" method="POST">
        <!-- si message d'erreur on l'affiche -->
        <?php if (isset($_SESSION['LOGIN_ERROR_MESSAGE'])) : ?>
            <div class="alert alert-danger" role="alert">
                <?php echo $_SESSION['LOGIN_ERROR_MESSAGE'];
                unset($_SESSION['LOGIN_ERROR_MESSAGE']); ?>
            </div>
        <?php endif; ?>
        <div class="mb-3">
            <label for="email" class="form-label">Email</label>
            <input type="email" class="form-control" id="email" name="email" aria-describedby="email-help" placeholder="you@exemple.com">
            <div id="email-help" class="form-text">L'email utilisé lors de la création de compte.</div>
        </div>
        <div class="mb-3">
            <label for="password" class="form-label">Mot de passe</label>
            <input type="password" class="form-control" id="password" name="password">
        </div>
        <button type="submit" class="btn btn-primary">Envoyer</button>
    </form>

    <!-- Si utilisateur/trice bien connectée on affiche un message de succès -->
<?php else : ?>
    <div class="alert alert-success" role="alert">
        Bonjour <?php echo $_SESSION['LOGGED_USER']['email']; ?> et bienvenue sur le site !
    </div>
<?php endif; ?>

Désormais, lors de la soumission du formulaire, nous appellerons le fichier submit_login.php :

<form action="submit_login.php" method="POST">

Ensuite, nous allons transférer le traitement du formulaire dans le fichier submit_login.php :

<?php
session_start();
require_once(__DIR__ . '/variables.php');
require_once(__DIR__ . '/functions.php');

/**
 * On ne traite pas les super globales provenant de l'utilisateur directement,
 * ces données doivent être testées et vérifiées.
 */
$postData = $_POST;

// Validation du formulaire
if (isset($postData['email']) &&  isset($postData['password'])) {
if (!filter_var($postData['email'], FILTER_VALIDATE_EMAIL)) {
     $_SESSION['LOGIN_ERROR_MESSAGE'] = 'Il faut un email valide pour soumettre le formulaire.';
} else {
     foreach ($users as $user) {
         if (
             $user['email'] === $postData['email'] &&
             $user['password'] === $postData['password']
         ) {
             $_SESSION['LOGGED_USER'] = [
                 'email' => $user['email'],
                 'user_id' => $user['user_id'],
             ];
         }
     }

     if (!isset($_SESSION['LOGGED_USER'])) {
         $_SESSION['LOGIN_ERROR_MESSAGE'] = sprintf(
             'Les informations envoyées ne permettent pas de vous identifier : (%s/%s)',
             $postData['email'],
             strip_tags($postData['password'])
         );
     }
}

redirectToUrl('index.php');
}

Attendez, c'est quoi cette fonction  redirectToUrl('index.php');  ? Je ne l'ai jamais vue auparavant. À quoi sert-elle ?

La fonction  redirectToUrl('index.php');  que nous utilisons dans ce contexte sert à rediriger l'utilisateur vers une autre page. Dans ce cas précis, elle nous redirige vers la page d'accueil du site, qui est située à l'URL index.php. Lorsqu'un utilisateur soumet le formulaire de connexion avec des informations correctes, nous souhaitons le rediriger vers la page d'accueil.

3. Ajoutons la fonction  redirectToUrl()  dans functions.php.

D'abord, voyons le code de cette fonction :

<?php
function redirectToUrl(string $url): never
{
    header("Location: {$url}");
    exit();
}

En utilisant la fonction  header("Location: {$url}")  , on indique au navigateur web qu'il doit charger une nouvelle page dont l'adresse est spécifiée par $url.

Ensuite,  exit()  est utilisé pour arrêter immédiatement le reste du code PHP. Cela garantit que la redirection s'effectue sans problème, sans que d'autres instructions perturbent ce processus.

En somme, la fonction  redirectToUrl  est utile pour envoyer vers une autre page web, par exemple après une connexion réussie, une action sur un formulaire ou toute autre situation où l'on souhaite que l'utilisateur soit redirigé vers une nouvelle page.

Conservez les données grâce aux cookies

Travailler avec des cookies revient à peu près à la même chose qu'avec des sessions, à quelques petites différences près que nous allons voir.

Voici ce que nous allons faire pour découvrir les cookies :

  1. On va voir ce qu'est exactement un cookie (parce que si ça se trouve, il y en a qui croient en ce moment même que je vais parler d'une recette de cuisine !).

  2. Ensuite, nous verrons comment écrire un cookie : c'est facile à faire, si on respecte quelques règles.

  3. Enfin, nous verrons comment récupérer le contenu d'un cookie : ce sera le plus simple.

Comprenez le fonctionnement d'un cookie

Par exemple, vous inscrivez dans un cookie le pseudo du visiteur. Comme ça, la prochaine fois qu'il viendra sur votre site, vous pourrez lire son pseudo en allant regarder ce que son cookie contient.

Parfois, les cookies ont une mauvaise image.

Non, ce ne sont pas des virus, juste de petits fichiers texte qui permettent de retenir des informations.

Au pire, un site marchand peut retenir que vous aimez les appareils photos numériques et vous afficher uniquement des pubs pour des appareils photos, mais c'est tout ; ces petites bêtes sont inoffensives pour votre ordinateur.

Où sont stockés les cookies sur mon disque dur ?

Cela dépend de votre navigateur web. Généralement, on ne touche pas directement à ces fichiers, mais on peut afficher à l'intérieur du navigateur la liste des cookies qui sont stockés.

On peut choisir de les supprimer à tout moment.

Si vous avez Mozilla Firefox, vous pouvez :

  1. Aller dans le menu "Paramètres" > "Vie privée et sécurité" > "Cookies et données de sites".

  2. Et cliquer sur "Gérer les données".

Vous obtenez la liste et la valeur de tous les cookies stockés, comme sur la figure suivante.

Capture d'écran qui montre la liste des cookies stockés sous Firefox. On voit qu'il y en a 15.
Cookies sous Firefox

Les cookies sont classés par site web. Chaque site web peut écrire, comme vous le voyez, plusieurs cookies. Les cookies sont donc des informations temporaires que l'on stocke sur l'ordinateur des visiteurs. La taille est limitée à quelques kilo-octets : vous ne pouvez pas stocker beaucoup d'informations à la fois, mais c'est en général suffisant.

Écrivez un cookie

Par exemple, le cookie utilisateur aurait chez moi la valeur : LOGGED_USER 

On lui donne en général trois paramètres, dans l'ordre suivant :

  1. Le nom du cookie (exemple : LOGGED_USER ).

  2. La valeur du cookie (exemple :  utilisateur@exemple.com ).

  3. La date d'expiration du cookie, sous forme de "timestamp" (exemple :  1090521508 ).

Si vous voulez supprimer le cookie dans un an, il vous faudra donc écrire :time() + 365*24*3600 

Cela aura pour effet de supprimer votre cookie dans exactement un an.

Sécurisez un cookie avec les propriétés httpOnly et secure

Configurons les options httpOnly et secure sur le cookie.

Voici comment créer un cookie de façon sécurisée :

<?php
// retenir l'email de la personne connectée pendant 1 an
setcookie(
    'LOGGED_USER',
    'utilisateur@exemple.com',
    [
        'expires' => time() + 365*24*3600,
        'secure' => true,
        'httponly' => true,
    ]
);

En écrivant les cookies de cette façon, vous diminuez le risque qu'un jour l'un de vos visiteurs puisse se faire voler le contenu d'un cookie à cause d'une faille XSS.

Affichez et récupérez un cookie

De ce fait, si je veux ressortir l'e-mail du visiteur que j'avais inscrit dans un cookie, il suffit d'écrire :  $_COOKIE['LOGGED_USER'] 

Ce qui nous donne un code PHP tout bête pour afficher de nouveau le pseudo du visiteur :

Bonjour <?php echo $_COOKIE['LOGGED_USER']; ?> !

Comme vous le voyez encore une fois, le gros avantage, c'est que les superglobales sont accessibles partout.

Modifiez un cookie existant

Vous vous demandez peut-être comment modifier un cookie déjà existant ? Il faut refaire appel à  setcookie en gardant le même nom de cookie, ce qui « écrasera » l'ancien.

Par exemple, si c'est Laurène Castor qui se connecte au site, je ferai :

<?php
setcookie(
    'LOGGED_USER',
    'laurene.castor@exemple.com',
    [
        'expires' => time() + 365*24*3600,
        'secure' => true,
        'httponly' => true,
    ]
);

Notez qu'alors le temps d'expiration du cookie est remis à zéro pour un an.

Exercez-vous

Et si nous ajoutions la fonctionnalité de déconnexion (logout) à votre site web !

Ah là là, encore un truc à ajouter ! Le chapitre était déjà super long… Et maintenant, la déconnexion ? J'ai vraiment besoin d'un coup de main !

Je comprends, ce chapitre a été assez dense, et l'ajout de la fonction de déconnexion peut sembler un peu intimidant. Mais ne vous inquiétez pas, pour rendre les choses plus simples, je vous suggère de diviser la tâche en étapes.

  1. Créez un nouveau fichier PHP et nommez-le logout.php.

  2. Dans ce fichier logout.php, programmez le code nécessaire pour déconnecter un utilisateur. Vous pouvez utiliser les connaissances que vous avez acquises jusqu'à présent dans ce cours pour gérer la session de l'utilisateur et supprimer ses données de connexion.

  3. Ensuite, redirigez l'utilisateur vers la page d'accueil (index.php) une fois la déconnexion effectuée.

  4. Dans le fichier header.php, ajoutez une condition pour afficher le lien vers logout.php uniquement si l'utilisateur est connecté. Cela permettra aux utilisateurs connectés d'accéder facilement à la déconnexion.

  5. Testez si la déconnexion fonctionne correctement sur le site web. Pour cela :

    1. Connectez-vous en utilisant l'email : mathieu.nebra@exemple.com et le mot de passe MiamMiam

    2. Une fois connecté, assurez-vous que le lien "Déconnexion" est visible.

    3. Cliquez sur le lien Déconnexion. Vérifiez que les informations de l'utilisateur ainsi que le lien Déconnexion disparaissent.

À vous de jouer !

En résumé

  • Les variables superglobales sont des variables automatiquement créées par PHP. Elles se présentent sous la forme de tableaux (arrays) contenant différents types d'informations.

  • Dans les chapitres précédents, nous avons découvert deux superglobales essentielles :  $_GET (qui contient les données issues de l'URL) et $_POST (qui contient les données issues d'un formulaire).

  • La superglobale $_SESSION permet de stocker des informations qui seront automatiquement transmises de page en page pendant toute la durée de visite d'un internaute sur votre site. Il faut au préalable activer les sessions en appelant la fonction  session_start() .

  • La superglobale $_COOKIE représente le contenu de tous les cookies stockés par votre site sur l'ordinateur du visiteur. Les cookies sont de petits fichiers que l'on peut écrire sur la machine du visiteur pour retenir par exemple son nom. On crée un cookie avec la fonction  setcookie() .

C'est la fin de cette partie du cours ! Et devinez quoi ? C'est le moment de répondre au quiz avant de passer à la suite et fin du cours.

Example of certificate of achievement
Example of certificate of achievement