Bonjour,

Voila je rencontre un petit problème avec mon code.
Je suis en fin de projet, un blog. Tout marche! Il ne me reste plus qu'une fonctionnalité et là, je bloque!

Mon code est construit avec une architecture MVC

Je voudrais faire une liste déroulante avec des items récupérés dans ma bases de données. Comme cette liste s'enrichit, j'utilise une boucle pour récupérer ces données.

Mais là j'obtiens un message d'erreur:

view\frontend\template.php:41:boolean false

J'ai donc un tableau vide en réponse de ma requête.
J'ai beau chercher, je ne comprends pas où est l'erreur :(
Quelqu'un pourrai-t-il m'expliquer?
Voici mes codes:
mon template.php

<li class="nav-item dropdown">

                        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Chapitres</a>

                            <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                            <?php while($data = $chapters->fetch()): ?>
                                <a class="dropdown-item" href="index.php?action=chapter&amp;id=<?= $data['id'] ?>"><?= $data['title'] ?></a>
                            <?php endwhile; ?>   
                            </div>

                          <?php var_dump($data);
                          die();
                          ?>

                    </li>

index.php

 } elseif ($_GET['action'] === 'chapter') {
            if (isset($_GET['id']) && $_GET['id'] > 0) {
                    chapter();
            }

le controller frontend.php

function listChapters()
{
    $chapterManager = new \Alaska\Blog\Model\ChapterManager();
    $chapters = $chapterManager->getChapters();

    include 'view/frontend/listChaptersView.php';
}

enfin, mon manager ChapterManager.php

public function getChapters()
    {
        $db = $this->dbConnect();
        $req = $db->query('SELECT id, title, content, DATE_FORMAT(creation_date, \'%d/%m/%Y à %Hh%imin%ss\') AS creation_date_fr FROM chapters ORDER BY creation_date');

        return $req;
    }

Je vous remarcie d'avance des idées, pistes que vous pourriez m'apporter :)

11 réponses


Salut,

Quelques remarques / pistes d'amélioration :

  • Que fait cette fonction chapter() dans index.php ?
  • Toujours dans index.php, tu utilises directement $_GET... Question sécurité, tu t'exposes à de sérieux problèmes!
  • As-tu essayé de placer ton var_dump juste après ta requête pour vérifier que les données sont bien renvoyées ?
  • Tu utilises php comme moteur de template, as-tu envisagé un outil tiers (smarty, twig)? C'est plus simple et c'est plus facile à l'intégration...
  • Pour la gestion de base de données, tu as Doctrine qui est un excellent ORM, qui ajoute une couche d'abstraction et te libère du lien avec mysql...
    Ou carrément Symfony ou Laravel en tant que framework, le temps d'apprentissage est largement compensé par le gain en dev par la suite ;)
Nin1363
Auteur

Merci pour ta réponse! :)
C'est un projet que je fais dans le cadre d'une formation, donc j'ai des impératifs pour la construction du code comme utiliser l'architecture MVC, orienté objet.
la fonction chapter(), c'est pour récupérer mes chapitres et commentaires

function chapter()
{
    $chapterManager = new \Alaska\Blog\Model\ChapterManager();
    $commentManager = new \Alaska\Blog\Model\CommentManager();

    $chapter = $chapterManager->getChapter($_GET['id']);
    $comments = $commentManager->getComments($_GET['id']);

    include 'view/frontend/chapterView.php';

}

je m'excuse par avance de ne pas tout comprendre :(
Tu me dis de mettre var_dump juste après la requête, c'est à dire juste après

 <?php while($data = $chapters->fetch()): ?>

Si oui, rien ne se passe....

Places tout d'abord un var_dump($chapter) dans ta fonction chapter() après récup des données pour vérifier quelles données sont renvoyées. Tu pourras ainsi vérifier que côté données, les choses se passent bien (ou pas).

Nin1363
Auteur

Merci pour ta réponse Digivia :)
Si je mets un var_ dump($chapters) dans ma fonction listchapters()

function listChapters()
{
    $chapterManager = new \Alaska\Blog\Model\ChapterManager();
    $chapters = $chapterManager->getChapters();

    var_dump($chapters);
    die();
    include 'view/frontend/listChaptersView.php';
}

J'obtiens le message

controller\frontend.php:30:
object(PDOStatement)[3]
public 'queryString' => string 'SELECT id, title, content, DATE_FORMAT(creation_date, '%d/%m/%Y à %Hh%imin%ss') AS creation_date_fr FROM chapters ORDER BY creation_date' (length=137)

Si je fais un var_dump($chapter) dans ma fonction chapter(), là rien ne se passe j'ai ma vue qui s'affiche avec dans mon dropdown juste une liste vide.

ton DATE_FORMAT %Hh%imin%ss << c'est bon ca ?? semble bizars

C'est bizarre que dans le var_dump($chapter) tu n'aie pas les résultats de requête... Tu peux tester avec un foreach (avec un var_dump à l'intérieur) pour balayer les résultats?
Ta table chapters contient bien des enregistrements?

Nin1363
Auteur

Ma table a bien des enregistrements puisque j'arrive à voir la liste de tous mes chapitres dans mon listChaptersView.php. c'est juste dans le menu de Bootstrap dropdown que je n'arrive pas à lister mes titres. Se pourrait-il qu'il puisse avoir un conflit quelconque?
Je mets mon code de listChaptersView.php

<?php $title = 'Billet pour l\'Alaska'; ?>

<?php ob_start(); ?>

<div class="container">
    <div class="jumbotron" id="accueil">
        <h1 class="chapitre">Billet pour l'Alaska</h1>
        <br>
        <h2 class="bienvenue">Bienvenue sur mon blog</h2>
        <br>
        <div class="row align-items-start">
            <img class="col-4" src="public/img/livre.jpg" alt="livre">
            <p class="col-8" id="bienvenue"><strong>Pour mon nouveau livre "Billet pour l'Alaska", je souhaiterai vous inviter à collaborer avec moi. Comment? Tout simplement en me laissant vos commentaires sur les chapitres que je mettrai en ligne. Vos commentaires seront une matière précieuse pour nourrir mon imagination.<br>Vous respecterez, bien entendu, un minimum de règles élémentaires juridiques et/ou de courtoisie (je me reserve le droit de supprimer ou non tous commentaires signalés).<br>
            Une nouvelle forme d'écriture, d'échanges entre les lecteurs et l'auteur.</strong> </p>
        </div>
    </div>
    <div class="jumbotron jumbotron-fluid">
        <h1 class="chapitre">Chapitres</h1>

    <?php while ($data = $chapters->fetch()): ?>

        <h2 class="title"><strong><?= ($data['title']) ?></strong></h2><p class="date"><em>le <?= $data['creation_date_fr'] ?></em></p>
        <p><?= mb_substr($data['content'], 0, 400, 'UTF-8') ?>....... <a href="index.php?action=chapter&amp;id=<?= $data['id'] ?>">Lire la suite</a></p>

    <?php endwhile; ?>

    </div>
</div>
<?php $content = ob_get_clean(); ?>

<?php require'template.php'; ?>

Et de mon template.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, shrink-to-fit=no">
    <title><?= $title ?></title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
    <link href='http://fonts.googleapis.com/css?family=Bitter' rel='stylesheet' type='text/css'>
    <link href="public/css/style.css" rel="stylesheet" />
    <link rel="shortcut icon" href="public/img/fond.ico">
</head>

<body id="page-top" data-spy="scroll" data-target=".navbar">

    <header>
       <!-- Navigation
      ================================================== -->
        <nav class="navbar navbar-expand-lg navbar fixed-top navbar-dark bg-dark">
            <a class="navbar-brand" href="index.php">Jean Forteroche</a><br><br>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarTogglerDemo01" aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarTogglerDemo01">
                <ul class="navbar-nav mr-auto mt-2 mt-lg-0">
                    <li class="nav-item">
                        <a class="nav-link" href="index.php">Accueil<span class="sr-only">(current)</span></a>
                    </li>
                    <li class="nav-item dropdown">

                        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Chapitres</a>

                            <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                            <?php while($data = $chapters->fetch()): ?>

                                <a class="dropdown-item" href="index.php?action=chapter&amp;id=<?= $data['id'] ?>"><?= $data['title'] ?></a>
                                <?php var_dump($data);
                            die();
                            ?>
                            <?php endwhile; ?>   
                            </div>

                        </li>
                    <li class="nav-item">
                        <a class="nav-link" href="index.php?action=connexion">Admin</a>
                    </li>
                </ul>
            </div>
        </nav>
    </header>

    <?= $content ?>

    <footer class="text-center">
        <a class="btn btn-default" href="#"><i class="fa fa-twitter fa-2x"></i></a>
        <a class="btn btn-default" href="#"><i class="fa fa-facebook fa-2x"></i></a>
        <a class="btn btn-default" href="#"><i class="fa fa-google-plus fa-2x"></i></a>
        <a class="btn btn-default" href="#"><i class="fa fa-flickr fa-2x"></i></a>
        <a class="btn btn-default" href="#"><i class="fa fa-spotify fa-2x"></i></a>
    </footer>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Javascript de Bootstrap -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>

</body>

</html>

Re merc pour les réponses :)

Je ne comprends pas pourquoi dans listChapters tu as :

$chapters = $chapterManager->getChapters();

et dans la fonction chapters() :

/* getChapter() sans "s" à la fin ? */
$chapters = $chapterManager->getChapter();
Nin1363
Auteur

Bonjour :)
Je n'ai pas de fonction chapters() mais une fonction chapter() (sans s)

C'est mon controller frontend.php

function listChapters()
{
    $chapterManager = new \Alaska\Blog\Model\ChapterManager();
    $chapters = $chapterManager->getChapters();

    include 'view/frontend/listChaptersView.php';
}

function chapter()
{
    $chapterManager = new \Alaska\Blog\Model\ChapterManager();
    $commentManager = new \Alaska\Blog\Model\CommentManager();

    $chapter = $chapterManager->getChapter($_GET['id']);
    $comments = $commentManager->getComments($_GET['id']);

    include 'view/frontend/chapterView.php';

}

Ensuite dans mon ChapterManager j'ai deux fonction
getChapters() qui récupère la liste de tous les chapitres
et
getChapter($chapterId) qui récupère un chapitre avec ses commentaires

 public function getChapters()
    {
        $db = $this->dbConnect();
        $req = $db->query('SELECT id, title, content, DATE_FORMAT(creation_date, \'%d/%m/%Y à %Hh%imin%ss\') AS creation_date_fr FROM chapters ORDER BY creation_date');

        return $req;
    }

    public function getChapter($chapterId)
    {
        $db = $this->dbConnect();
        $req = $db->prepare('SELECT id, title, content, DATE_FORMAT(creation_date, \'%d/%m/%Y à %Hh%imin%ss\') AS creation_date_fr FROM chapters WHERE id = ?');
        $req->execute(array($chapterId));
        $chapter = $req->fetch();

        return $chapter; 
    }
Nin1363
Auteur

Bonjour! çà y est j'ai trouvé! On m'a aidé à comprendre pourquoi çà ne pouvait pas marcher.
En fait, je voulais atteindre des variables qui n'étaient accessible que depuis le $content de mon template.php
Il a donc fallu que je rajoute quelques lignes de php au tout début de ce fichier

<?php 

$chapterManager = new \Alaska\Blog\Model\ChapterManager();
$chapters = $chapterManager->getChapters();
?>

<!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, shrink-to-fit=no">
    <title><?= $title ?></title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
    <link href='http://fonts.googleapis.com/css?family=Bitter' rel='stylesheet' type='text/css'>
    <link href="public/css/style.css" rel="stylesheet" />
    <link rel="shortcut icon" href="public/img/fond.ico">
</head>

Je te remercie de ton aide, de ta patience :)