Erreur: Call to a member function prepare() on null

Résolu
lemega
Messages postés
85
Date d'inscription
mardi 13 janvier 2009
Statut
Membre
Dernière intervention
13 janvier 2020
- Modifié le 23 janv. 2019 à 12:09
lemega
Messages postés
85
Date d'inscription
mardi 13 janvier 2009
Statut
Membre
Dernière intervention
13 janvier 2020
- 24 janv. 2019 à 11:05
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

lemega
Messages postés
85
Date d'inscription
mardi 13 janvier 2009
Statut
Membre
Dernière intervention
13 janvier 2020
1
24 janv. 2019 à 01:23
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'];
1
jordane45
Messages postés
35442
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
19 mai 2022
356
24 janv. 2019 à 09:12
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);
    }

 }
 
?>
0
jordane45
Messages postés
35442
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
19 mai 2022
356
23 janv. 2019 à 14:40
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);






0
lemega
Messages postés
85
Date d'inscription
mardi 13 janvier 2009
Statut
Membre
Dernière intervention
13 janvier 2020
1
23 janv. 2019 à 17:00
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|
0
jordane45
Messages postés
35442
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
19 mai 2022
356
23 janv. 2019 à 17:21
Il manque un underscore en effet
parent::_construct();

A remplacer par :
parent::__construct();
0
jordane45
Messages postés
35442
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
19 mai 2022
356
23 janv. 2019 à 17:21
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.
0
lemega
Messages postés
85
Date d'inscription
mardi 13 janvier 2009
Statut
Membre
Dernière intervention
13 janvier 2020
1
23 janv. 2019 à 17:57
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.
0
jordane45
Messages postés
35442
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
19 mai 2022
356
Modifié le 23 janv. 2019 à 19:41
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);
  
?>
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
lemega
Messages postés
85
Date d'inscription
mardi 13 janvier 2009
Statut
Membre
Dernière intervention
13 janvier 2020
1
24 janv. 2019 à 11:05
Ok.... Thank you.... Very good

Tout fonctionne a merveille. Voici le resultat:


Encore une fois merci, grand merci pour ton assistance.
0