Erreur: Call to a member function prepare() on null [Résolu]

Signaler
Messages postés
85
Date d'inscription
mardi 13 janvier 2009
Statut
Membre
Dernière intervention
13 janvier 2020
-
Messages postés
85
Date d'inscription
mardi 13 janvier 2009
Statut
Membre
Dernière intervention
13 janvier 2020
-
Bonjour à tous,

J'ai besoin de votre aide pour resoudre une erreur qui ne rend vraiment fou.

Mon API se connecter à une db SQL Server comme suit (fichier config/db.php):
<?php 
 class sql { 
  private $connexion_sql;
  function __construct() { 
   $this->connexion_bdd = new PDO('sqlsrv:Server=servername;Database=db_name', 'username', 'password');
   // Fixe les options d'erreur (ici nous utiliserons les exceptions)
   $this->connexion_bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
  }
   
  public function requete($requete) { 
   $prepare = $this->connexion_bdd->prepare($requete); $prepare->execute();
   return $prepare;
  }
 }
 
 
?>


J'ai ensuite créé une classe de ma table fruit(objects/fruits.php):
<?php
 class Fruit{
 
  // database connection and table name
  private $conn;
  private $table_name = "tFruits";
  
  // object properties
  public $id;
  public $name;
  
  // constructor with $db as database connection
  public function __construct($db){
   $this->conn = $db;
  }
  
  // read products
  function read(){
   
   // select all query
   $query = "SELECT * FROM " . $this->table_name . " ORDER BY name ASC";
   
   // prepare query statement
   $stmt = $this->conn->prepare($query);
   
   // execute query
   $stmt->execute();
   
   return $stmt;
  }
 }
?>


Pour lire les fruits j'ai fait ceci (fruit/read.php) :
<?php
 // include database and object files
 include_once '../config/db.php';
 include_once '../objects/fruits.php';
 
 $sql = new sql();
 $db = $sql->__construct();
 
 //$req = $sql->requete('SELECT * FROM tFruits'); 
 //while ($r = $req->fetch()) { 
 /// print_r($r); 
 //}
 
 
 
 //$statement = 'SELECT * FROM tFruits';
 //$sth = $sql->prepare($statement, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
 //$num = $sth->rowCount();
 //$sth->execute();
 
 $fruit = new Fruit($db);
 // query fruits
 $stmt = $fruit->read();
 $num = $stmt->rowCount();
 
 if($num>0){
  
  // fruits array
  $fruits_arr=array();
  $fruits_arr["records"]=array();
  
  while ($row = $stmt->fetchAll(PDO::FETCH_ASSOC)){ 
   
   extract($row);
   
   $fruit_item=array(
    "id" => $id,
    "name" => $name
   );
  
   array_push($fruits_arr["records"], $fruit_item);
  }
  
  // set response code - 200 OK
  http_response_code(200);
  
  // show fruits data in json format
  echo json_encode($fruits_arr);
 }
 
 else{
 
  // set response code - 404 Not found
  http_response_code(404);
  
  // tell the user no products found
  echo json_encode(
   array("message" => "No fruits found.")
  );
 }
?>


lorsque je lance le fichier read.php dans u interpretur de json, j'obtiens l'erreur suivante:
Fatal error: Uncaught Error: Call to a member function prepare() on null in C:\....\objects\fruits.php on line 24


Cette ligne 24 du fichier fruits.php correspondau code suivant:
$stmt = $this->conn->prepare($query);


Fraichement je n'y comprends rien...

Alors, SVP j'ai besoin d'un coup de pousse.

Merci d'avance

EDIT : Correction des balises de code (ajout du langage )
A voir également:

5 réponses

Messages postés
85
Date d'inscription
mardi 13 janvier 2009
Statut
Membre
Dernière intervention
13 janvier 2020
1
Wahou, merci de me montrer cette autre facette du php. ça montre tout son charme.. lol

On a l'erreur suivante :
 Error: Cannot use object of type PDOStatement as array in ...\config\dbase.php on line 34


Cette ligne correspond a :
return  empty($prep['ERROR']) ? $prep->fetchAll() : $prep['ERROR'];
Messages postés
32144
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
22 avril 2021
345
Ouppsssss.. en effet.

Change le ficher comme ceci :
class Database { 
  
  protected $connexion_bdd;
    
  function __construct() { 
      try{
        $this->connexion_bdd = new PDO('sqlsrv:Server=DATA-SERVER\CHATBOTSERVER;Database=chatbotdb', 'sa', 'Germain09');
        //  Fixe les options d'erreur (ici nous utiliserons les exceptions)
        $this->connexion_bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
      } catch(PDOException $e) {
          die('Erreur : ' . $e->getMessage());
      }
  }
  
    
  private function requete($requete,$datas=NULL) { 
      try{
        $prepare = $this->connexion_bdd->prepare($requete); 
        $prepare->execute($datas);
        return $prepare;
      }catch(Exception $e){
        // en cas d'erreur :
         print_r (array('ERROR'=>" Erreur ! ".$e->getMessage(),'SQL'=>$requete, 'datas'=>$datas);
         exit();
      }
  }
    
    /**
    * Retourne tous les enregistrements d'une requête SELECT
    */
    public function db_All($sql,$datas=NULL){
      $prep = $this->requete($sql,$datas);
      return  $prep->fetchAll() ;
    }
    
    /**
    * Retourne le premier enregistrements d'une requête SELECT
    */
    public function db_One($sql,$datas=NULL){
      $prep = $this->requete($sql,$datas);
      return  $prep->fetch();
    }
    
    /**
    * Permet d'exécuter n'importe quel type de requête
    * A utiliser pour autre chose que les selects...
    */
    public function db_exec($sql,$datas=NULL){
      return $this->requete($sql,$datas);
    }

 }
 
?>
Messages postés
32144
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
22 avril 2021
345
Bonjour,

Plusieurs erreurs dans ton code....

Dans le fichier de connexion..
Tu as la variable
private $connexion_sql;

mais toi tu essayes de stocker la connexion dans :
$this->connexion_bdd


Ensuite...
Dans read.php
$sql = new sql();
 $db = $sql->__construct();

1 - la méthode construct est appellée automatiquement lors du new. (c'est un constructeur)
Il ne faut pas l'appeller ensuite....

2 - Tu penses que ton construct te retourne la connexion.... sauf que tu n'as aucun RETURN dans le code de ton constructeur....
A la limite, tu pourrais récupérer la variable $connexion_sql .. mais tu l'as déclaré en PRIVATE...
Donc.. soit tu code un GETTER pour pouvoir récupérer le contenu de cette variable (c'est le plus propre)
Soit tu ajoutes un RETURN dans ton construct()

3 - A la place... as tu déjà entendu parlé d'héritage ? De "extends" ?
Regarde donc... c'est bien pratique...
class sql { 
  protected $connexion_bdd;
  function __construct() { 
   $this->connexion_bdd = new PDO('sqlsrv:Server=servername;Database=db_name', 'username', 'password');
   // Fixe les options d'erreur (ici nous utiliserons les exceptions)
   $this->connexion_bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
  }

class Fruit extends bdd{
// database connection and table name
   private $table_name = "tFruits";
  
  // object properties
  public $id;
  public $name;
  
  // constructor with $db as database connection
  public function __construct($db){
    parent::_construct();
  }
 
 // read products
  function read(){
   
   // select all query
   $query = "SELECT * FROM " . $this->table_name . " ORDER BY name ASC";
   
   // prepare query statement
   $stmt = $this->connexion_bdd->prepare($query);






Messages postés
85
Date d'inscription
mardi 13 janvier 2009
Statut
Membre
Dernière intervention
13 janvier 2020
1
Grand merci a to jordane45,

j'ai apporte des modifications selon vos critiques et observations

le fichier db.php donne:
<?php 
class Database {

protected $connexion_bdd;
function __construct() {
$this->connexion_bdd = new PDO('sqlsrv:Server=DATA-SERVER\CHATBOTSERVER;Database=chatbotdb', 'sa', 'Germain09');
// Fixe les options d'erreur (ici nous utiliserons les exceptions)
$this->connexion_bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}

public function requete($requete) {
$prepare = $this->connexion_bdd->prepare($requete);
$prepare->execute();
return $prepare;
}

}

?>


Le fichier objects/fruits.php on a:
<?php


class Fruit extends Database{
// Nom de la table
private $table_name = "tFruits";

// object properties
public $id;
public $name;

// constructor with $db as database connection
public function __construct(){
parent::_construct();
}

// Lire les fruits
function read(){

// select all query
$query = "SELECT * FROM " . $this->table_name . " ORDER BY name ASC";

// preparer query statement
$stmt = $this->connexion_bdd->prepare($query);

// Executer query
$stmt->execute();

return $stmt;
}
}
?>


enfin le fichier fruit/read.php donne:
<?php
// required headers
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");

// inclure database et fichier object
include_once '../config/db.php';
include_once '../objects/fruits.php';

//Instancier la database
$database = new Database();

//Initialisation de l'objet fruits
$fruit = new Fruit();

// query fruits
$stmt = $fruit->read();
$num = $stmt->rowCount();

if($num>0){

// fruits array
$fruits_arr=array();
$fruits_arr["records"]=array();

while ($row = $stmt->fetchAll(PDO::FETCH_ASSOC)){

extract($row);

$fruit_item=array(
"id" => $id,
"name" => $name
);

array_push($fruits_arr["records"], $fruit_item);
}

// set response code - 200 OK
http_response_code(200);

// show fruits data in json format
echo json_encode($fruits_arr);
}

else{

// set response code - 404 Not found
http_response_code(404);

// tell the user no products found
echo json_encode(
array("message" => "No fruits found.")
);
}
?>


donc lorsque j'execute le fichier read.php, on obtient l'erreur suivante:
Fatal error: Uncaught Error: Call to undefined method Database::_construct() in ...\objects\fruits.php on line 14


Cette ligne correspond au code suivant:
public function __construct(){
parent::_construct();
}


Encore une fois, merci de m'apporter ton assistance.
Je suis un débutant |o|
Messages postés
32144
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
22 avril 2021
345
Il manque un underscore en effet
parent::_construct();

A remplacer par :
parent::__construct();
Messages postés
32144
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
22 avril 2021
345
tu noteras que le code que je te montre est en couleur.... contrairement au tient...
cela vient du fait que tu utilises mal les balises de code...

Explications sur leur fonctionnement ici :
https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
Merci de le faire à l'avenir.
Messages postés
85
Date d'inscription
mardi 13 janvier 2009
Statut
Membre
Dernière intervention
13 janvier 2020
1
Super, vraiment super....

Mais je pense qu'il y a un petit truc qui de fonctionne pas bien
Normalement, on doit avoir les donnees contenues dans la table tFruits
au lieu de cela on obtient
{
"message": "No fruits found."
}

comme si la table est vide.
Messages postés
32144
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
22 avril 2021
345
Essaye ça :

<?php

 class Database { 
  
  protected $connexion_bdd;
    
  function __construct() { 
      try{
        $this->connexion_bdd = new PDO('sqlsrv:Server=DATA-SERVER\CHATBOTSERVER;Database=chatbotdb', 'sa', 'Germain09');
        //  Fixe les options d'erreur (ici nous utiliserons les exceptions)
        $this->connexion_bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
      } catch(PDOException $e) {
          die('Erreur : ' . $e->getMessage());
      }
  }
  
    
  private function requete($requete,$datas=NULL) { 
      try{
        $prepare = $this->connexion_bdd->prepare($requete); 
        $prepare->execute($datas);
        return $prepare;
      }catch(Exception $e){
        // en cas d'erreur :
         return array('ERROR'=>" Erreur ! ".$e->getMessage());
      }
  }
    
    /**
    * Retourne tous les enregistrements d'une requête SELECT
    */
    public function db_All($sql,$datas=NULL){
      $prep = $this->requete($sql,$datas);
      return  empty($prep['ERROR']) ? $prep->fetchAll() : $prep['ERROR'];
    }
    
    /**
    * Retourne le premier enregistrements d'une requête SELECT
    */
    public function db_One($sql,$datas=NULL){
      $prep = $this->requete($sql,$datas);
      return  empty($prep['ERROR']) ? $prep->fetch() : $prep['ERROR'];
    }
    
    /**
    * Permet d'exécuter n'importe quel type de requête
    * A utiliser pour autre chose que les selects...
    */
    public function db_exec($sql,$datas=NULL){
      return $this->requete($sql,$datas);
    }

 }
 
?>

 <?php
 class Fruit extends Database{
  // Nom de la table
  private $table_name = "tFruits";
    
  // object properties
  public $id;
  public $name;
    
  // constructor with $db as database connection
  public function __construct(){
   parent::__construct();
  }
   
  /**
    * Retourne la liste des fruits
    * return Array
    */
  function read(){
        // select all query
        $query = "SELECT id, name FROM " . $this->table_name . " ORDER BY name ASC";
        $result = $this->db_All($query);
        return $result;
  }
    
    /**
    * Retourne Un des fruits en fonction de son id
    * param : id -> id d'un fruit
    * return Array contenant les infos d'un fruit
    */
  function get_FruitById($id){
        // select all query
        $query = "SELECT id, name FROM " . $this->table_name . " 
                  WHERE id =:id 
                  ORDER BY name ASC";
        $datas = array(':id'=>$id);         
        $result = $this->db_One($query,$datas);
        return $result;
  }
 }
?>

<?php
 // required headers
 header("Access-Control-Allow-Origin: *");
 header("Content-Type: application/json; charset=UTF-8");
 
 // inclure database et fichier object
 include_once '../config/db.php';
 include_once '../objects/fruits.php';
  
  function sendResponse($response,$statusCode=404){
    http_response_code($statusCode);
    echo json_encode($response);
  }
 
 //Instancier la database
 $database = new Database();
 
 //Initialisation de l'objet fruits
 $fruit = new Fruit();
 
 // query fruits
 $arrFruits = $fruit->read();
 $num = !empty($arrFruits) ? count($arrFruits) : 0;
 
 if($num>0){
  $response = array("records"=>$arrFruits);
  // set response code - 200 OK
  $codeResult = 200;
 } else{
   // set response code - 404 Not found
  $codeResult = 404;
  // tell the user no products found
   $response = array("message" => "No fruits found.")
 }
  
  sendResponse($response,$codeResult);
  
?>
Messages postés
85
Date d'inscription
mardi 13 janvier 2009
Statut
Membre
Dernière intervention
13 janvier 2020
1
Ok.... Thank you.... Very good

Tout fonctionne a merveille. Voici le resultat:


Encore une fois merci, grand merci pour ton assistance.