Salut tout le monde, je suis actuellement la formation sur la POO, et je suis face un problème que je n'arrive pas à résoudre.

Je suis coincé à 16:07 avec l'erreur suivante :
Fatal error: in D:\wamp\www\grafikart\core\Database\MysqlDatabase.php on line 31
PDOException: in D:\wamp\www\grafikart\core\Database\MysqlDatabase.php on line 31

Autre point, j'ai remarqué grâce à PhpStorm qu'il ne trouvait pas ma fonction last(). Or elle est bien dans mon fichier PostTable :

<?php

namespace App\Table;

use Core\Table\Table;

class PostTable extends Table{

/**
 * Récupère les derniers articles
 * @return array
 */
public function last(){
    return $this->query("
    SELECT articles.id, articles.titre, articles.contenu, articles.date, categories.titre as categorie
    FROM articles
    LEFT JOIN categories ON category_id = categories.id
    WHERE articles.id = ?
    ORDER BY articles.date DESC");
}
}

Et appelé sur la home

<div class="row">
<div class="col s8">
    <?php foreach(App::getInstance()->getTable('Post')->last() as $post): ?>

        <h2><a  class="red-text text-lighten-2" href="<?= $post->url ?>"><?= $post->titre; ?></a>16:14 (trouver quand on crée la fonction last()</h2>

        <p><em><?= $post->categorie; ?></em></p>

        <p><?= $post->extrait; ?></p>

    <?php endforeach; ?>
</div>

Si quelqu'un aurait une solution, car moi je sèche ^^

12 réponses


Naïr
Réponse acceptée

Avant de remplacer par des variables les éléments de ta chaîne de connexion, il faudrait être sûr que la connexion en "dur" fonctionne.

$pdo = new PDO('mysql:dbname=blog;host=localhost', 'root', '');

Autre chose, dans ta fonction last(), ta requête SQL n'est pas bonne (c'est peut être l'origine du problème ...)
Tu indiques dans ta requête que tu vas lui transmettre un paramètre pour le WHERE, hors ce n'est pas une requête préparée que tu es sensé réaliser (le bon vieux copier/merder)

SELECT articles.id, articles.titre, articles.contenu, articles.date, categories.titre as categorie
FROM articles
LEFT JOIN categories ON category_id = categories.id
WHERE articles.id = ? => A SUPPRIMER
ORDER BY articles.date DESC"

Salut,

Il faudrait nous en montrer d'avantage pour que l'on puisse t'aider, et notamment le contenu de MysqlDatabase.php.
Si tu essaye getTable('Posts') au lieu de getTable('Post') ça ne marche pas mieux ?

YahikO
Auteur

C'est vrai que c'est mieux avec le fichier MysqlDatabase ..

<?php
namespace Core\Database;
use \PDO;

class MysqlDatabase extends Database {

private $db_name;
private $db_user;
private $db_pass;
private $db_host;
private $pdo;

public function __construct($db_name, $db_user='root', $db_pass = 'root', $db_host = 'localhost') {

    $this->db_name = $db_name;
    $this->db_user = $db_user;
    $this->db_pass = $db_pass;
    $this->db_host = $db_host;
}

private function getPDO() {
    if($this->pdo === null) {
        $pdo = new PDO('mysql:dbname=blog;host=localhost', 'root', '');
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->pdo = $pdo;
    }
    return $this->pdo;
}

public function query($statement, $class_name = null, $one = false) {
    $req = $this->getPDO()->query($statement);
    if($class_name === null){
        $req->setFetchMode(PDO::FETCH_OBJ);
    } else {
        $req->setFetchMode(PDO::FETCH_CLASS, $class_name);
    }
    if ($one) {
        $datas = $req->fetch();
    } else {
        $datas = $req->fetchAll();
    }
    return $datas;
}

public function prepare($statement, $attributes, $class_name, $one = false) {
    $req = $this->getPDO()->prepare($statement);
    $req->execute($attributes);
    $req->setFetchMode(PDO::FETCH_CLASS, $class_name);
    if ($one) {
        $datas = $req->fetch();
    } else {
        $datas = $req->fetchAll();
    }
    return $datas;
}

}   

Posts ne change rien :/

A priori je dirais que la connexion avec la BD ne s'effectue pas correctement. Je t'invite donc à vérifier tes identifiants de connexion, et en particulier le user et le pass.

YahikO
Auteur

J'ai bien vérifié, mais mes identifiants et ma BDD correspondent bien..

J'ai toujours ce message :

http://www.evernote.com/shard/s267/sh/dfd7dcc3-ec85-402c-ae00-c22d1ffcbd80/2743ba99d6a9a9e8d95ac7fe208e52fb

YahikO
Auteur

Petit up, je n'ai toujours pas trouvé la solution :(

As tu essayé de faire un var_dump($this->pdo) avant le return dans getPDO() ?

L'erreur vient de ctte fonction:

private function getPDO() {
    if($this->pdo === null) {
        $pdo = new PDO('mysql:dbname=blog;host=localhost', 'root', ''); // Les infos de connexions sont fausses !!!
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->pdo = $pdo;
    }
    return $this->pdo;
}

Il n'y a rien qui te choque ? Tu passes en variables d'instance de la classe MysqlDatabase les informations de connexion à la base de données, mais tu ne les retranscrits pas lors de la dite connexion. Je vois que ton mdp est 'root' et, lors de l'instanciation de l'objet PDO, tu mets ''.
Y'a pas comme un problème ? ;)

YahikO
Auteur

Naïr : le var dump me retourne

object(PDO)[5]

betaWeb : c'était une erreur de ma part, il n'y a pas de mot de passe. En revanche dans le construct, l'ordre n'est pas le même -> db name, db user, db pass et db host alors dans mon new PDO, j'ai : db name, db host, db user et db pass. C'est normal ? Je n'ai rien trouvé sur la doc de php

Quel rapport avec l'ordre lors de la construction de la classe MysqlDatabase ?? Tu as juste à faire ça :

 $pdo = new PDO('mysql:' . $this->db_name . '=blog;host=' . $this->db_hosy, $this->db_user, $this->db_pass);

Je ne comprends pas ce qui te bloque ?

YahikO
Auteur

Ce qui me bloque, c'est que même en remplaçant par des pointeurs, ça ne fonctionne toujours pas. Pour le coup je suis sur de mes identifiants. DB : blog, user : root et pas de mp.

Je dois louper quelque chose ^^

YahikO
Auteur

Merci beaucoup à vous deux et surtout à toi Naïr. Le problème venait bien de ma fonction last().
Le fameux copier / coller ... :)