Fatal error: Uncaught Error: Call to a member function query() [Résolu/Fermé]

Signaler
Messages postés
262
Date d'inscription
mardi 10 novembre 2015
Statut
Membre
Dernière intervention
6 septembre 2020
-
Messages postés
262
Date d'inscription
mardi 10 novembre 2015
Statut
Membre
Dernière intervention
6 septembre 2020
-
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

Messages postés
31198
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
25 janvier 2021
3 212
Bonjour,

Commence par ça :
https://www.commentcamarche.net/faq/46512-pdo-gerer-les-erreurs

(en ajoutant, aussi bien dans ta connexion PDO que pour CHAQUE requête un bloc TRY/CATCH )

Et au passage .... A quel endroit, dans ton fichier index.view.php instancies tu la class Database ?
Car là .. ta variable $bdd est "null" d'où ton message d'erreur....

Messages postés
262
Date d'inscription
mardi 10 novembre 2015
Statut
Membre
Dernière intervention
6 septembre 2020
14
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,
Messages postés
262
Date d'inscription
mardi 10 novembre 2015
Statut
Membre
Dernière intervention
6 septembre 2020
14
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,