• 15 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 11/06/2019

[Nouvelle fonctionnalité] Afficher des commentaires

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Ca y est, on vient de vous demander une nouvelle fonctionnalité ! On aimerait pouvoir afficher une page avec les commentaires de chaque billet.

Vous vous souvenez du lien "Commentaires" sous chaque billet ?

Il est temps de faire marcher ce lien
Il est temps de faire marcher ce lien "Commentaires" !

Lorsqu'on clique dessus, on va afficher une page avec le billet et sa liste de commentaires.

Hum, mais comment s'y prendre avec une architecture MVC ? 🤔

Mise à jour du modèle

On commence en général par écrire le modèle. C'est l'endroit de notre code où on récupère les données. C'est là qu'on y écrit nos requêtes SQL notamment.

Tout d'abord, ajoutons une table pour gérer les commentaires dans la base. Elle aura cette structure :

La structure de la table comments
La structure de la table comments

Ajoutez-la dans votre base de données (en passant par phpMyAdmin par exemple).

Maintenant, concentrons-nous sur le code du modèle. Pour l'instant, notre fichier model.php  ne contient qu'une seule fonction getPosts qui récupère tous les derniers posts de blog.

On va écrire 2 nouvelles fonctions :

  • getPost (au singulier !) : récupère un post précis en fonction de son ID.

  • getComments : récupère les commentaires associés à un ID de post.

Cela donne :

<?php
function getPosts()
{
    // ... (déjà écrite)
}

function getPost($postId)
{
    try
    {
        $db = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', 'root');
    }
    catch(Exception $e)
    {
        die('Erreur : '.$e->getMessage());
    }

    $req = $db->prepare('SELECT id, title, content, DATE_FORMAT(creation_date, \'%d/%m/%Y à %Hh%imin%ss\') AS creation_date_fr FROM posts WHERE id = ?');
    $req->execute(array($postId));
    $post = $req->fetch();

    return $post;
}

function getComments($postId)
{
    try
    {
        $db = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', 'root');
    }
    catch(Exception $e)
    {
        die('Erreur : '.$e->getMessage());
    }

    $comments = $db->prepare('SELECT id, author, comment, DATE_FORMAT(comment_date, \'%d/%m/%Y à %Hh%imin%ss\') AS comment_date_fr FROM comments WHERE post_id = ? ORDER BY comment_date DESC');
    $comments->execute(array($postId));

    return $comments;
}

Ces deux nouvelles fonctions prennent un paramètre : l'id du post qu'on recherche. Cela nous permet notamment de ne sélectionner que les commentaires liés au post concerné.

Hum, mais il y a quelque chose qui me dérange ici. 🤔
Je n'aime pas voir du code se répéter. C'est le cas en particulier de la connexion à la base de données avec les blocs try/catch. Allez, on va factoriser ça !

Je vous propose tout simplement de créer une fonction dbConnect() qui va renvoyer la connexion à la base de données. Je l'ajoute à la fin du fichier :

<?php
function getPosts()
{
    $db = dbConnect();
    $req = $db->query('SELECT id, title, content, DATE_FORMAT(creation_date, \'%d/%m/%Y à %Hh%imin%ss\') AS creation_date_fr FROM posts ORDER BY creation_date DESC LIMIT 0, 5');

    return $req;
}

function getPost($postId)
{
    $db = dbConnect();
    $req = $db->prepare('SELECT id, title, content, DATE_FORMAT(creation_date, \'%d/%m/%Y à %Hh%imin%ss\') AS creation_date_fr FROM posts WHERE id = ?');
    $req->execute(array($postId));
    $post = $req->fetch();

    return $post;
}

function getComments($postId)
{
    $db = dbConnect();
    $comments = $db->prepare('SELECT id, author, comment, DATE_FORMAT(comment_date, \'%d/%m/%Y à %Hh%imin%ss\') AS comment_date_fr FROM comments WHERE post_id = ? ORDER BY comment_date DESC');
    $comments->execute(array($postId));

    return $comments;
}

// Nouvelle fonction qui nous permet d'éviter de répéter du code
function dbConnect()
{
    try
    {
        $db = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', 'root');
        return $db;
    }
    catch(Exception $e)
    {
        die('Erreur : '.$e->getMessage());
    }
}

Ah, c'est tout bête, mais je me sens déjà un peu mieux. 😅

Création du contrôleur

Nous avions déjà écrit un contrôleur index.php  pour gérer la liste des derniers billets. Je vous propose d'écrire un autre contrôleur post.php qui affiche un post et ses commentaires.

<?php
require('model.php');

if (isset($_GET['id']) && $_GET['id'] > 0) {
    $post = getPost($_GET['id']);
    $comments = getComments($_GET['id']);
    require('postView.php');
}
else {
    echo 'Erreur : aucun identifiant de billet envoyé';
}

Ce contrôleur est légèrement plus complexe que le précédent (mais pas beaucoup !).

Il fait un test, un contrôle : il vérifie qu'on a bien reçu en paramètre un id dans l'url ( $_GET['id'] ).
Si c'est le cas, il appelle les 2 fonctions du modèle dont on va avoir besoin : getPost et getComments . On récupère ça dans des variables, qui seront réutilisées dans la vue : postView.php .

Création de la vue

Il nous faut maintenant créer cette vue postView.php  qu'on appelle dans le contrôleur. C'est normalement facile si vous avez bien suivi jusqu'ici et ne devrait poser aucune difficulté.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Mon blog</title>
        <link href="style.css" rel="stylesheet" /> 
    </head>
        
    <body>
        <h1>Mon super blog !</h1>
        <p><a href="index.php">Retour à la liste des billets</a></p>

        <div class="news">
            <h3>
                <?= htmlspecialchars($post['title']) ?>
                <em>le <?= $post['creation_date_fr'] ?></em>
            </h3>
            
            <p>
                <?= nl2br(htmlspecialchars($post['content'])) ?>
            </p>
        </div>

        <h2>Commentaires</h2>

        <?php
        while ($comment = $comments->fetch())
        {
        ?>
            <p><strong><?= htmlspecialchars($comment['author']) ?></strong> le <?= $comment['comment_date_fr'] ?></p>
            <p><?= nl2br(htmlspecialchars($comment['comment'])) ?></p>
        <?php
        }
        ?>
    </body>
</html>

Dans cette vue, on affiche le billet (récupéré avec $post ) et les commentaires (récupérés dans$comments ). Testez, ça doit fonctionner !

Le blog affiche les commentaires... avec une structure MVC sous le capot !
Le blog affiche les commentaires... avec une structure MVC sous le capot !

En résumé

Nous avons maintenant les fichiers suivants :

  • model.php : le modèle, qui contient différentes fonctions pour récupérer des informations dans la base.

  • index.php : le contrôleur de la page d'accueil. Il fait le lien entre le modèle et la vue.

  • indexView.php : la vue de la page d'accueil. Elle affiche la page.

  • post.php : le contrôleur d'un billet et ses commentaires. Il fait le lien entre le modèle et la vue.

  • postView.php : la vue d'un billet et ses commentaires. Elle affiche la page.

Essayez donc le code !

https://www.codevolve.com/api/v1/publishable_key/2A9CAA3419124E3E8C3F5AFCE5306292?content_id=ca023344-98b9-4b61-b3a7-2bed89b2519f

Exemple de certificat de réussite
Exemple de certificat de réussite