Correction



Si vous lisez ces lignes, c'est que vous devez être venus à bout de ce TP. Celui-ci ne présentait pas de difficultés particulières mais il constituait l'occasion de vous exercer un peu plus avec MySQL, tout en faisant appel aux fonctions et dates en SQL.


index.php : la liste des derniers billets

Le TP est constitué de deux pages. Voici la correction que je vous propose pour la page index.php qui liste les derniers billets du blog :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">

    <head>

        <title>Mon blog</title>

        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

    <link href="style.css" rel="stylesheet" type="text/css" /> 

    </head>

         

    <body>

        <h1>Mon super blog !</h1>

        <p>Derniers billets du blog :</p>

  

<?php

// Connexion à la base de données

try

{

    $bdd = new PDO('mysql:host=localhost;dbname=test', 'root', '');

}

catch(Exception $e)

{

        die('Erreur : '.$e->getMessage());

}

 

// On récupère les 5 derniers billets

$req = $bdd->query('SELECT id, titre, contenu, DATE_FORMAT(date_creation, \'%d/%m/%Y à %Hh%imin%ss\') AS date_creation_fr FROM billets ORDER BY date_creation DESC LIMIT 0, 5');

 

while ($donnees = $req->fetch())

{

?>

<div class="news">

    <h3>

        <?php echo htmlspecialchars($donnees['titre']); ?>

        <em>le <?php echo $donnees['date_creation_fr']; ?></em>

    </h3>

     

    <p>

    <?php

    // On affiche le contenu du billet

    echo nl2br(htmlspecialchars($donnees['contenu']));

    ?>

    <br />

    <em><a href="commentaires.php?billet=<?php echo $donnees['id']; ?>">Commentaires</a></em>

    </p>

</div>

<?php

} // Fin de la boucle des billets

$req->closeCursor();

?>

</body>

</html>

Vous constaterez que tous les textes sont protégés par htmlspecialchars(), y compris les titres. J'utilise par ailleurs une fonction qui doit être nouvelle pour vous : nl2br(). Elle permet de convertir les retours à la ligne en balises HTML <br />. C'est une fonction dont vous aurez sûrement besoin pour conserver facilement les retours à la ligne saisis dans les formulaires.


Côté SQL, cette page n'exécute qu'une seule requête : celle qui récupère les cinq derniers billets.

SELECT id, titre, contenu, DATE_FORMAT(date_creation, '%d/%m/%Y à %Hh%imin%ss') AS date_creation_fr FROM billets ORDER BY date_creation DESC LIMIT 0, 5

On récupère toutes les données qui nous intéressent dans cette table, en mettant la date en forme au passage. Pour cela, on utilise la fonction scalaire DATE_FORMAT qui nous permet d'obtenir une date dans un format français.


Les billets sont ordonnés par date décroissante, le plus récent étant donc en haut de la page.

Enfin, chaque billet est suivi d'un lien vers la page commentaires.php qui transmet le numéro du billet dans l'URL :

<a href="commentaires.php?billet=<?php echo $donnees['id']; ?>">Commentaires</a>


commentaires.php : affichage d'un billet et de ses commentaires

Cette page présente des similitudes avec la précédente mais elle est un peu plus complexe. En effet, pour afficher un billet ainsi que ses commentaires, nous avons besoin de faire deux requêtes SQL :

  • une requête pour récupérer le contenu du billet ;
  • une requête pour récupérer les commentaires associés au billet.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">

    <head>

        <title>Mon blog</title>

        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

    <link href="style.css" rel="stylesheet" type="text/css" /> 

    </head>

         

    <body>

        <h1>Mon super blog !</h1>

        <p><a href="index.php">Retour à la liste des billets</a></p>

  

<?php

// Connexion à la base de données

try

{

    $bdd = new PDO('mysql:host=localhost;dbname=test', 'root', '');

}

catch(Exception $e)

{

        die('Erreur : '.$e->getMessage());

}

 

// Récupération du billet

$req = $bdd->prepare('SELECT id, titre, contenu, DATE_FORMAT(date_creation, \'%d/%m/%Y à %Hh%imin%ss\') AS date_creation_fr FROM billets WHERE id = ?');

$req->execute(array($_GET['billet']));

$donnees = $req->fetch();

?>

 

<div class="news">

    <h3>

        <?php echo htmlspecialchars($donnees['titre']); ?>

        <em>le <?php echo $donnees['date_creation_fr']; ?></em>

    </h3>

     

    <p>

    <?php

    echo nl2br(htmlspecialchars($donnees['contenu']));

    ?>

    </p>

</div>

 

<h2>Commentaires</h2>

 

<?php

$req->closeCursor(); // Important : on libère le curseur pour la prochaine requête

 

// Récupération des commentaires

$req = $bdd->prepare('SELECT auteur, commentaire, DATE_FORMAT(date_commentaire, \'%d/%m/%Y à %Hh%imin%ss\') AS date_commentaire_fr FROM commentaires WHERE id_billet = ? ORDER BY date_commentaire');

$req->execute(array($_GET['billet']));

 

while ($donnees = $req->fetch())

{

?>

<p><strong><?php echo htmlspecialchars($donnees['auteur']); ?></strong> le <?php echo $donnees['date_commentaire_fr']; ?></p>

<p><?php echo nl2br(htmlspecialchars($donnees['commentaire'])); ?></p>

<?php

} // Fin de la boucle des commentaires

$req->closeCursor();

?>

</body>

</html>


Ce code est un peu gros mais on peut le découper en deux parties :

  • affichage du billet ;
  • affichage des commentaires.


La requête qui récupère le billet ressemble à celle de la page précédente, à la différence près qu'il s'agit d'une requête préparée car elle dépend d'un paramètre : l'id du billet (fourni par $_GET['billet'] qu'on a reçu dans l'URL).

Comme on récupère forcément un seul billet, il est inutile de faire une boucle. L'affichage est identique à celui qu'on faisait pour chaque billet sur la page précédente, à l'exception du lien vers la page des commentaires qui ne sert plus à rien (puisque nous sommes sur la page des commentaires).


On pense à libérer le curseur après l'affichage du billet avec :

<?php

$req->closeCursor();

?>

En effet, cela permet de « terminer » le traitement de la requête pour pouvoir traiter la prochaine requête sans problème.


La récupération des commentaires se fait ensuite via la requête suivante :

SELECT auteur, commentaire, DATE_FORMAT(date_commentaire, '%d/%m/%Y à %Hh%imin%ss') AS date_commentaire_fr FROM commentaires WHERE id_billet = ? ORDER BY date_commentaire

Vous noterez que l'on ne se connecte à la base de données qu'une fois par page. Pas besoin donc de se connecter à nouveau pour effectuer cette seconde requête.


On récupère avec cette requête tous les commentaires liés au billet correspondant à l'id reçu dans l'URL. Les commentaires sont triés par dates croissantes comme c'est habituellement le cas sur les blogs, mais vous pouvez changer cet ordre si vous le désirez, c'est facile.

Créé avec HelpNDoc Personal Edition: Optimisez sans effort votre site Web de documentation pour les moteurs de recherche