Bonjour à tous,

Après avoir réalisé une structure de blog en PHP, j'ai découvert l'architecture MVC et les bases de la POO.
Je cherche donc à améliorer mon travail pour respecter l'architecture MVC, notamment en utilisant des classes :)

Mon code "non legit" fonctionne, il compte le nombre de commentaire pour chaque billet de blog (pour écrire "Voir les commentaires (nombre de commentaires)").

Voici ce code :

MODEL :

function countComments($id_post)
{
    $bdd = dbConnect();
    $comments_number = $bdd->prepare('SELECT COUNT(*) AS number_of_comments FROM blog_comments WHERE id_post= ?');
    $comments_number->execute(array($id_post));
    return $comments_number;
}

VUE (je ne passe même pas par le contrôleur et j'y met direct une fonction haha)

    while ($display_blog = $blog->fetch())
    {
        $comments_number = countComments($display_blog['id']);

        $display_comment_nb = $comments_number->fetch();

        echo '<a href="index.php?comment=' . $display_blog['id'] . '">';

       if (! $display_comment_nb['number_of_comments'] == 0)
        {
            echo 'Voir les commentaires (' . $display_comment_nb['number_of_comments'] . ') </a>';
        }

        else
        {
            echo 'Il n\'y a pas de commentaire sur ce billet. Cliquez ici pour en ajouter un. </a>';
        }
    }

La boucle While permet l'affichage de chaque billet de blog grâce à une requête SQL SELECT.

On se rend donc compte que ma fonction est dépendante d'une variable dans la vue (l'id du billet de blog). Donc si je mets ma fonction countComments dans une classe, ça ne fonctionnera plus.

J'ai essayé de recréer dans ma fonction countComment ce While en appelant ma fonction qui affiche chaque billet de blog, mais ça ne fonctionne pas. Je suppose que c'est parce que du coup mon while s'applique 2 fois (une fois dans la fonction countComment, et une fois après, à l'affichage des billets). J'ai essayé de retourner un tableau, toujours sans résultat probant.
J'ai essayé de ne plus dépendre d'une variable en comptant le nombre de commentaires pour chaque billet de blog et retourner un tableau dans l'ordre, mais forcément quand il n'y a pas de commentaire il n'y a pas de ligne dans ma table, donc j'ai des valeurs nulles au lieu de zéro.
Par exemple si j'ai en nombre de commentaires dans l'ordre : 0 - 1 - 3 - 0 - 0 -2 - 0 - 0 - 0
Lui va me retourner 1 - 3 - 2

Jusque là je m'en suis toujours sorti mais là j'ai besoin d'être guidé, il y a une bonne méthode c'est sûr, mais je n'arrive pas à la trouver...
Des idées ? :)

Merci d'avance !

6 réponses


Drx
Auteur
Réponse acceptée

Bon, j'ai avancé, juste après avoir posté j'ai réussi à obtenir un tableau qui match avec mon nombre de commentaires :)

Par contre, je ne comprends pas pourquoi il y a une valeur 0 à chaque fois ?

Le truc c'est que quand j'essaye d'afficher chaque valeur de ce tableau dans mon While, ça repart de zéro à chaque page :(. Donc si par exemple sur ma dernière page de 5 billets j'ai dans l'ordre ce nombre de commentaires : 2 - 3 - 1 - 0 - 0
Ca affichera ça, mais sur chacune de mes pages...


(
    [0] => Array
        (
            [number_of_comments] => 2
            [0] => 2
        )

    [1] => Array
        (
            [number_of_comments] => 3
            [0] => 3
        )

    [2] => Array
        (
            [number_of_comments] => 1
            [0] => 1
        )

    [3] => Array
        (
            [number_of_comments] => 0
            [0] => 0
        )
)
Drx
Auteur
Réponse acceptée

Bon bah résolu !

J'y aurais mis plusieurs jours...

Il suffisait de bien prendre ma requête SQL qui a comme LIMIT les 5 billets à chaque page (j'avais dupliqué cette requête et supprimé cet endroit pour l'utiliser dans ma fonction countComment, car je croyais que ça me polluait)

Si le code intéresse quelqu'un, pas de souci je le posterai

Curvata
Réponse acceptée

Salut,

tu pourrais faire un truc dans le genre:

class table 
{
    private $pdo;

    public function __construct(\PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    public function countComments(int $id_post)
    {
        $s = $this->pdo->prepare('SELECT COUNT(id) FROM blog_comments WHERE id_post = ?');
        $s->execute([$id_post]);
        return $s->fetchColumn();
    }

    public function getCommentsForBillet(int $id_post)
    {
        $s = $this->pdo->prepare('SELECT * FROM blog_comments WHERE id_post = ?');
        $s->execute([$id_post]);
        return $s->fetchAll(PDO::FETCH_CLASS, comment::class);
    }

    public function getBillets()
    {
        $s = $this->pdo->prepare('SELECT * FROM blog_billet');
        $s->execute();
        return $s->fetchAll(PDO::FETCH_CLASS, billet::class);
    }
}
class comment 
{
    private $id;
    private $title;
    private $content;

    public function getId()
    {
        return $this->id;
    }
    public function getTitle()
    {
        return $this->title;
    }
    public function getContent()
    {
        return $this->content;
    }
}
class billet 
{
    private $id;
    private $title;
    private $content;

    public function getId()
    {
        return $this->id;
    }
    public function getTitle()
    {
        return $this->title;
    }
    public function getContent()
    {
        return $this->content;
    }
}
$pdo = new PDO(........);
$table = new table($pdo);
$billets = $table->getBillets();

foreach ($billets as $billet)
{
    $comments_number = $this->table->countComments($billet->getId());
    echo '<a href="index.php?comment=' . $billet->getId() . '">';
        if (!$comments_number == 0) {
            echo 'Voir les commentaires (' . $comments_number . ') </a>';
        } else {
            echo 'Il n\'y a pas de commentaire sur ce billet. Cliquez ici pour en ajouter un. </a>';
        }
}
$comments = $table->getCommentsForBillet((int)$_GET['comment']);

foreach ($comments as $comment)
{
    echo "<h1>" . $comment->getTitle() . "</h1>";
    echo "<p>" . $comment->getContent() . "</p>";
}
Drx
Auteur

Hello Curvata,

Wahou merci d'avoir pris le temps de faire une réponse aussi complète !

Dans l'idée j'ai utilisé la même logique, même si mon code n'a rien à voir, il est pas aussi clean. Je ne connais pas fetchAll et fetchColumn, mais ça a l'air plus adapté.
Je vais peut être pouvoir essayer d'améliorer mon travail en me basant sur le tiens :)

Pour le moment, voici mon code :

Class PostManager

    public function listPosts()
    {
        $limit_page = $this->getLIMIT();
        $db = $this->dbConnect();
        $blog_post = $db->prepare('SELECT id, title, message, DATE_FORMAT(post_date, \'%d/%m/%Y\') AS post_date, 
                                   HOUR(post_time) AS hour_post_time, 
                                   MINUTE(post_time) AS minute_poste_time
                                   FROM blog_posts ORDER BY ID DESC LIMIT :limit_page, 5');

        $blog_post->bindValue('limit_page', $limit_page, PDO::PARAM_INT);
        $blog_post->execute();

        return $blog_post;
    } 

Classe CommentManager

    public function countComments()
    {
        $array = array();
        $postManager = new PostManager();
        $blog = $postManager->listPosts();

        while ($display_blog = $blog->fetch())
        {
        $db = $this->dbConnect();
        $req = $db->prepare('SELECT COUNT(*) AS number_of_comments FROM blog_comments WHERE id_post= ?');
        $req->execute(array($display_blog['id']));
        $comments_number = $req->fetch();
        $array[] = $comments_number;
        }
        return $array;
    }

Je passe sur le controlleur et l'index, rien de sorcier

index_view

        while ($display_blog = $blog->fetch())
        {
            echo '<br><h3>' . htmlspecialchars($display_blog['title']) . '</h3>Posté le ' . $display_blog['post_date'] . ', à ' . $display_blog['hour_post_time'] . 'h' .
                $display_blog['minute_poste_time'] . '<br>' . nl2br(htmlspecialchars($display_blog['message'])) . '<br><a href="index.php?comment=' .
                $display_blog['id'] . '"> ';

            $display_nb = $comments_number[$increment_comments_number++]['number_of_comments'];

            if (! $display_nb == 0)
            {
                echo 'Voir les commentaires (' . $display_nb . ') </a>';
            }

            else
            {
                echo 'Il n\'y a pas de commentaire sur ce billet. Cliquez ici pour en ajouter un. </a>';
            }
        }

Bonsoir.
Niveau performances ce n'est pas top ton système.
Le mieux serait que tu ajoutes dans la table blog_posts une colonne par exemple nommée comments_count qui par défaut aurait la valeur 0.
Lorsqu'un nouvel enregistrement est sauvegardé dans la table blog_comments, tu incrémentes la valeur de la colonne de l'enregistrement correspondant dans la table blog_posts.
Ce qui t'évitera de faire des requêtes SQL supplémentaires lorsque tu récupères les enregistrements de la table blog_posts.

Drx
Auteur

Hello Lartak,

Oui c'est plus intelligent effectivement, merci de l'astuce :)