Fatal error: Uncaught Error: Call to a member function query()

Résolu
Bonjour,
Je suis en train de tester une classe Database, il me retourne l'erreur suivante après avoir fait un update. Voilà les sources:
1 - Source index.php :
<?php
// Autoload
require './vendor/autoload.php';

$date = new Date();


$bdd = new Database('datalib');

if (isset($_GET['confirme']) && !empty($_GET['confirme'])) {
     $confirme = (int) $_GET['confirme'];
     $req = $bdd->update('UPDATE membres SET confirme = 1 WHERE id = ?', [$confirme]);
}

include './views/index.view.php';

2 - Source classe Database :
<?php

class Database
{
    private $db_name;
    private $db_host;
    private $db_user;
    private $db_pass;
    private $dsn;
    private $pdo;
    // Connection à la base de donnée
    public function __construct($db_name, $db_user = 'root', $db_pass = '', $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()
    {
        $this->dsn = "mysql:dbname={$this->db_name};host={$this->db_host};charset=utf8";
        if ($this->pdo === null) {
            $pdo = new PDO($this->dsn, $this->db_user, $this->db_pass);
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->pdo = $pdo;
            return $pdo;
        }
    }
    public function query($stmt)
    {
        $req   = $this->getPDO()->query($stmt);
        $datas = $req->fetchAll(PDO::FETCH_OBJ);
        return $datas;
    }
    public function update($stmt, $params = [])
    {
        $req   = $this->getPDO()->prepare($stmt)->execute($params);
    }
}

3 - Source index.view.php :
<!DOCTYPE html>
<html lang="fr">

	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
	   <meta http-equiv="X-UA-Compatible" content="ie=edge">
		<title>Test PDO</title>
		<!-- Typographie -->
    	<link href="https://fonts.googleapis.com/css?family=Open+Sans|Roboto:100,300,400,500,700" rel="stylesheet">
		<!-- Style CSS -->
    	<link rel="stylesheet" href="./css/bootstrap.css">
    	<link rel="stylesheet" href="./css/app.css">
    	<link rel="stylesheet" href="./css/sticky-footer.css">
		<!-- Scripts -->
		<script src="./js/time.js"></script>
	</head>

	<body>
		<div class="header">
			<div class="date">
				<?= $date->toDay() ?><br>
				<?= '(semaine ' . $date->week() . ') ' ?>
				<?= '(jour ' . $date->dayofYear() . ') ' ?>
				<?= '(' . $date->reste() . ')' ?>
			</div>
			<h1 class="text-center"><a href="/">Test Classe PDO</a></h1>	
			<div class="time" id="time">
				<script>window.onload=dsptime('time');</script>
			</div>	
		</div>
		<div class="container">
			
			<table class="table table-bordered table-striped">
				<caption><h4>Liste des membres</h4></caption>
				<thead class="text-center">
					<tr>
						<th scope="col">Identifiant</th>
						<th scope="col">Nom</th>
						<th scope="col">Pseudo</th>
						<th colspan="2" class="text-center">Action</th>
					</tr>
				</thead>
				<tbody>
					<?php foreach ($bdd->query('SELECT * FROM membres') as $m) : ?>
                        <?= '<tr><td class="text-center">'  . $m->id ?>
                        <?= '</td><td class="text-center">' . $m->name ?>
                        <?= '</td><td class="text-center">' . $m->pseudo ?>
                        <?php if ($m->confirme == 0) : ?>
                            <?= '</td><td scope="row" class="text-center"><a href="index.php?confirme='. $m->id . '" class="btn btn-success btn-sm">Confirmer</a>' ?>
                        <?php else : ?>
                                <?= '</td><td scope="row" class="text-center"><button class="btn btn-secondary btn-sm">Confirmé ' ?> 
                        <?php endif; ?>
                            <?= '</td><td scope="row" class="text-center"><a href="index.php?supprime='. $m->id . '" class="btn btn-danger btn-sm">Supprimer</a>' ?>                        
                            <?= '</td></tr>' ?>                         
                    <?php endforeach; ?>
            </tbody>
         </table>
      </div>
      <footer class="footer text-center">
        <div class="container">
                <span>Copyright © 2017 - <?= date('Y') ?> <a href="">Amaury le Cour</a>. Tous droits réservés</span>      
        </div>
      </footer>
   </body>

</html>

Egalement une capture de l'erreur :

Je ne vois pas comment faire, merci de m'aider
Cordialement,

3 réponses

  1. Bonjour Jordane45,
    J'ai modifié ma classe Database comme suit:
    <?php
    
    class Database
    {
        private $db_name;
        private $db_host;
        private $db_user;
        private $db_pass;
        private $dsn;
        private $pdo;
        private $error;
        // Connection à la base de donnée
        public function __construct($db_name, $db_user = 'root', $db_pass = '', $db_host = 'localhost')
        {
            $this->db_name  = $db_name;
            $this->db_user  = $db_user;
            $this->db_pass  = $db_pass;
            $this->db_host  = $db_host;
            // Définir le dsn
            $this->dsn = "mysql:dbname={$this->db_name};host={$this->db_host};charset=utf8";
            // Connexion à la base de donnée
            try {
                $pdo = new PDO($this->dsn, $this->db_user, $this->db_pass);
                $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                $this->pdo = $pdo;
            } catch (PDOException $e) {
                $this->error = $e->getMessage();
            }
        }
    
        public function query($stmt)
        {
            $req   = $this->pdo->query($stmt);
            $datas = $req->fetchAll(PDO::FETCH_OBJ);
            return $datas;
        }
        public function update($stmt, $params = [])
        {
            $req   = $this->pdo->prepare($stmt)->execute($params);
        }
        public function delete($stmt, $params = [])
        {
            $req   = $this->pdo->prepare($stmt)->execute($params);
        }
    }
    

    Maintenant cela marche comme je veux, voilà mon fichier index.php :
    <?php
    // Autoload
    require './vendor/autoload.php';
    
    // Date du jour
    $date = new Date();
    
    // Connexion à la base de donnée
    $bdd = new Database('datalib');
    
    if (isset($_GET['confirme']) && !empty($_GET['confirme'])) {
         $confirme = (int) $_GET['confirme'];
         $req = $bdd->update('UPDATE membres SET confirme = 1 WHERE id = ?', [$confirme]);
    }
    
    if (isset($_GET['supprime']) && !empty($_GET['supprime'])) {
         $supprime = (int) $_GET['supprime'];
         $req = $bdd->delete('DELETE FROM membres WHERE id = ?', [$supprime]);
    }
    
    include './views/index.view.php';
    

    Et dans le fichier index.view.php, j'ai juste modifié la ligne suivante:
    <?php foreach ($bdd->query('SELECT * FROM membres') as $m) : ?>
    

    Encore merci pour ton aide, je vais mettre ce sujet en résolu.
    Cordialement,
    1. Bonjour,
      La class Database, je le fais dans le fichier index.php. Dans la fonction getPDO() il se connecte à la base.
      Dans le fichier index.view.php, la connexion se fait avec la fonction query
      <?php foreach ($bdd->query('SELECT * FROM membres') : ?>.
      Le problème vient lorsque je clique sur un bouton Confirmer qui fait un update de la table, et c'est au retour, il se plante à l'instruction :
      <?php foreach ($bdd->query('SELECT * FROM membres') : ?>
      Je vais essayé de me connecter dans la fonction __contruct et non dans la fonction hetPDO().
      Effectivement j'ajouterais le bloc (TRY/CATCH).
      Si cela marche, je te tiendrai au courant.
      Cordialement,