Call to a member function execute() on a non-object

Call to a member function execute() on a non-object - PHP - Programmation

Marsh Posté le 15-01-2009 à 16:22:04    

Bonjour,
 
J'ai un petit problème avec un bout de code pompé :whistle:. Bizarrement, il passe sous WAMP mais pas sous Apache/PHP, en bref en dev Ok, en prod pas OK. Je cherche depuis un moment ce qui bloque mais je ne vois pas très bien.
 

Code :
  1. $desired_theme_id = NULL;
  2. if (!empty($_GET['theme']) and is_numeric($_GET['theme']))
  3.  $desired_theme_id = intval($_GET['theme']);
  4. else
  5. {
  6.  if (empty($_SESSION['current_theme']))
  7.   $desired_theme_id = DEFAULT_THEME_ID;
  8. }
  9. if($desired_theme_id)
  10. {
  11.  $sql = 'SELECT id, nom, repertoire FROM themes WHERE id = :id_theme';
  12.  $statement = $db->prepare($sql);
  13.  $statement->execute(array(':id_theme' => $desired_theme_id));
  14.  if (!($theme = $statement->fetch()) or !is_dir(THEMES_ROOT_FOLDER.'/'.$theme['repertoire']))
  15.  {
  16.   $statement->execute(array(':id_theme' => DEFAULT_THEME_ID));
  17.   $theme = $statement->fetch();
  18.  }
  19.  $_SESSION['current_theme'] = $theme['repertoire'];
  20. }


Erreur : "Fatal error: Call to a member function execute() on a non-object in /var/www/common.php on line 62", la ligne 62 correspond à la 16 ici, le tableau GET ne contient rien car c'est la homepage (domaine.net), les constantes sont bien initialisées :

Code :
  1. define('DEFAULT_THEME_ID', 1);
  2. define('THEMES_ROOT_FOLDER', 'themes');


Merci d'éclairer ma lanterne.

Reply

Marsh Posté le 15-01-2009 à 16:22:04   

Reply

Marsh Posté le 15-01-2009 à 16:28:44    

Bonjour.
 
Apparemment, ce qui ne lui plait pas c'est ça :

Code :
  1. $statement->execute(array(':id_theme' => $desired_theme_id));


A priori, je dirais que $statement n'est pas défini comme un objet - en prod'.
 
Essaye de faire un

Code :
  1. var_dump($statement);

avant le execute, ça devrait te donner des informations.
A voir :
Créer une page php avec juste  

Code :
  1. <?php
  2. phpinfo();
  3. ?>

Et regarde s'il n'y a pas des différences entre l'environnement de dév' et celui de prod'...

Reply

Marsh Posté le 15-01-2009 à 16:47:25    

Le "var_dump($statement);" retourne ceci :

Code :
  1. object(PDOStatement)#2 (1) { ["queryString"]=>  string(59) "SELECT id, nom, repertoire FROM themes WHERE id = :id_theme" }


Pour phpinfo(), je regarde tout de suite.

Reply

Marsh Posté le 15-01-2009 à 16:52:52    

Le var_dump te donne la même chose dans les deux environnements ?

Reply

Marsh Posté le 15-01-2009 à 17:02:22    

Oui c'est identiquement la même chose. Du côté de phpinfo aussi mise à part que le prod est configuré pour être sécurisé.

Reply

Marsh Posté le 15-01-2009 à 17:26:23    

par sécurisé, faut comprendre "safe_mode" à On? Parce que je sais que ce genre de mode pose pas mal de pb à de nombreux scripts php...


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 15-01-2009 à 17:39:36    

Non, il est désactivé aussi en prod.

Reply

Marsh Posté le 15-01-2009 à 17:50:32    

question bête : la connexion à la bd est ok? En gros que dans le ficheir de conf, t'as pas laissé le nom de la bd de test? Parce qu'à aucun moment dans ton script tu ne testes ce que contient $statement
 (la ligne $db->prepare($sql) pourrait très bien renvoyer une erreur, mais n'étant pas familier avec PDO...)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 15-01-2009 à 18:16:26    

Le nom de la base de donnée est la même, login et mot de passe sont adaptés.

Reply

Marsh Posté le 15-01-2009 à 18:30:45    

Gavrinis a écrit :

Le "var_dump($statement);" retourne ceci :

Code :
  1. object(PDOStatement)#2 (1) { ["queryString"]=>  string(59) "SELECT id, nom, repertoire FROM themes WHERE id = :id_theme" }


Pour phpinfo(), je regarde tout de suite.


 
à la ligne 61 ?

Reply

Marsh Posté le 15-01-2009 à 18:30:45   

Reply

Marsh Posté le 15-01-2009 à 18:34:59    

Bon c'est résolu, il y avait bien une erreur (merci Rufo ;)).
Maintenant j'ai droit à une autre ... "Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in /var/www/includes/functions.php on line 72 Warning"
 

Code :
  1. $desired_lang_id = NULL;
  2. if (!empty($_GET['lang']) && ($_GET['lang'] == 'fr' || $_GET['lang'] == 'en'))
  3.  $desired_lang_id = $_GET['lang'];
  4. else
  5. {
  6.  if (empty($_SESSION['language_id']) or empty($_SESSION['language_short']))
  7.   $desired_lang_id = DEFAULT_LANG_ID;
  8. }


La ligne 72 correspond ici à la ligne 3, je lui mets une condition "si le paramètre est vide va au else", bien sûr que le paramètre est vide car c'est comme au dessus nous sommes sur la homepage, mais seulement il parcourt quand même le if et après vient se plaindre :sweat:

Reply

Marsh Posté le 15-01-2009 à 18:36:55    


Non mon "var_dump($statement);" était à la ligne 60.

Reply

Marsh Posté le 15-01-2009 à 19:15:14    

J'ai parlé trop vite, il me sort toujours l'erreur précédente mais cette fois en ligne 60 (ligne 14 de mon premier post) en plus de la nouvelle erreur :(

Reply

Marsh Posté le 16-01-2009 à 09:33:03    

Gavrinis a écrit :

Code :
  1. $desired_lang_id = NULL;
  2. if (!empty($_GET['lang']) && ($_GET['lang'] == 'fr' || $_GET['lang'] == 'en'))
  3.  $desired_lang_id = $_GET['lang'];
  4. else
  5. {
  6.  if (empty($_SESSION['language_id']) or empty($_SESSION['language_short']))
  7.   $desired_lang_id = DEFAULT_LANG_ID;
  8. }


La ligne 72 correspond ici à la ligne 3, je lui mets une condition "si le paramètre est vide va au else", bien sûr que le paramètre est vide car c'est comme au dessus nous sommes sur la homepage, mais seulement il parcourt quand même le if et après vient se plaindre :sweat:


Si le script passe dans ta condition IF, c'est qu'elle est validée...
 
Tu as testé voir s'il y passe effectivement (echo par exemple) ?
Essaye de fractionner ton test. C'est peut-être moins optimisé, mais ce sera plus simple à maintenir :

Code :
  1. // Tableau contenant les langues utilisables
  2. $Tlang = array ( "fr", "en" );
  3. // Langage par défaut : la première du tableau des langues
  4. $desired_lang_id = $Tlang[0];
  5. // On commmence par regarder si un langage est demandé dans la session
  6. // Je n'ai pas tout suivi, dans ton script donc je fais le minimum...
  7. if ( isset ($_SESSION['language_id'] ) && ( ! empty ($_SESSION['language_id'] ) {
  8. // Je pars du principe que le contenu de SESSION est correct. Sinon, faire une vérif.
  9.    $desired_lang_id = $_SESSION['language_id'];
  10. }
  11. // ensuite on regarde si un langage est demandé par le GET
  12. if (isset ( $_GET['lang'] ) ) && ( in_array ( $_GET['lang'], $Tlang ) ) {
  13.    $desired_lang_id = $_GET['lang'];
  14. }


 
 
Ceci-dit, je ne pense pas que ce soit cette ligne qui te génére un Warning: PDOStatement...
 
Sinon, vu que tu utilises PDO - ou une variante :

Code :
  1. $sql = 'SELECT id, nom, repertoire FROM themes WHERE id = :id_theme';
  2. //En cas d'échec du PREPARE, $statement vaudra FALSE...
  3. // Du coup, on teste sa valeur avant de continuer...
  4. if ( $statement = $db -> prepare ( $sql ) ) {
  5. // La fonction execute renvoie TRUE si elle est bien passée, FALSE sinon
  6.    $statement->execute(array('id_theme' => $desired_theme_id)) or die ( "Erreur à l'execution du statement " );
  7. }
  8. else {
  9.    die ( "Erreur de statement avec la requête ".$sql );
  10. }


Apparemment, d'après la doc PHP, tu devrais préciser dans ton prepare un array...

Reply

Marsh Posté le 16-01-2009 à 09:40:18    

Gavrinis a écrit :

Bon c'est résolu, il y avait bien une erreur (merci Rufo ;)).
Maintenant j'ai droit à une autre ... "Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in /var/www/includes/functions.php on line 72 Warning"
 


Ca me paraît plus simple à résoudre. il te dit que le paramètrre passé n'est pas défini. Soit $_GET['lang'] contient rien (auquel cas voir pourquoi) soit il contient une valeur qui n'est pas un nombre. Attention, en général, ce qui est passé dans du GET ou POST est vu comme un type string. PDO fait sans doute la distinction entre la valeur 1 et "1". Si $_GET['lang'] n'est aps vide, essayes de faire (integer)$_GET['lang'] pour forcer le type.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 17-01-2009 à 10:44:30    

macgawel a écrit :


Si le script passe dans ta condition IF, c'est qu'elle est validée...

 

Tu as testé voir s'il y passe effectivement (echo par exemple) ?
Essaye de fractionner ton test. C'est peut-être moins optimisé, mais ce sera plus simple à maintenir :

Code :
  1. // Tableau contenant les langues utilisables
  2. $Tlang = array ( "fr", "en" );
  3. // Langage par défaut : la première du tableau des langues
  4. $desired_lang_id = $Tlang[0];
  5. // On commmence par regarder si un langage est demandé dans la session
  6. // Je n'ai pas tout suivi, dans ton script donc je fais le minimum...
  7. if ( isset ($_SESSION['language_id'] ) && ( ! empty ($_SESSION['language_id'] ) {
  8. // Je pars du principe que le contenu de SESSION est correct. Sinon, faire une vérif.
  9.    $desired_lang_id = $_SESSION['language_id'];
  10. }
  11. // ensuite on regarde si un langage est demandé par le GET
  12. if (isset ( $_GET['lang'] ) ) && ( in_array ( $_GET['lang'], $Tlang ) ) {
  13.    $desired_lang_id = $_GET['lang'];
  14. }
 


Ceci-dit, je ne pense pas que ce soit cette ligne qui te génére un Warning: PDOStatement...

 

Sinon, vu que tu utilises PDO - ou une variante :

Code :
  1. $sql = 'SELECT id, nom, repertoire FROM themes WHERE id = :id_theme';
  2. //En cas d'échec du PREPARE, $statement vaudra FALSE...
  3. // Du coup, on teste sa valeur avant de continuer...
  4. if ( $statement = $db -> prepare ( $sql ) ) {
  5. // La fonction execute renvoie TRUE si elle est bien passée, FALSE sinon
  6.    $statement->execute(array('id_theme' => $desired_theme_id)) or die ( "Erreur à l'execution du statement " );
  7. }
  8. else {
  9.    die ( "Erreur de statement avec la requête ".$sql );
  10. }


Apparemment, d'après la doc PHP, tu devrais préciser dans ton prepare un array...


Le problème s'est qu'un echo ne changera rien car le $_GET['lang'] est sensé ne rien contenir lors de l'arrivé sur la page, le echo n'affichera donc rien.
J'ai mis ton test mais ça n'a rien changé :(.
Ta solution pour le Warning me donne ceci "Erreur de statement avec la requ�te SELECT id, nom, repertoire FROM themes WHERE id = :id_theme"
Pour le prepare Ok mais je ne vois pas quel array mettre :??:


Message édité par Gavrinis le 17-01-2009 à 11:58:55
Reply

Marsh Posté le 17-01-2009 à 10:47:52    

rufo a écrit :


Ca me paraît plus simple à résoudre. il te dit que le paramètrre passé n'est pas défini. Soit $_GET['lang'] contient rien (auquel cas voir pourquoi) soit il contient une valeur qui n'est pas un nombre. Attention, en général, ce qui est passé dans du GET ou POST est vu comme un type string. PDO fait sans doute la distinction entre la valeur 1 et "1". Si $_GET['lang'] n'est pas vide, essayes de faire (integer)$_GET['lang'] pour forcer le type.


Il ne contient rien car quand le visiteur arrive sur la homepage, il n'y a pas encore de paramètre dans l'url, c'est pour cela qu'il y a une alternative avec les sessions.
Sa valeur contenue n'est effectivement pas un nombre étant donné que c'est soit "fr" soit "en".

Reply

Marsh Posté le 27-01-2009 à 16:32:06    

[:undertaker666]

Reply

Marsh Posté le 28-01-2009 à 10:45:21    

[:sh@rdar]

Citation :

Exemple #1 Prépare une requête SQL avec des paramètres nommés
<?php
/* Exécute une requête préparée en passant un tableau de valeurs */
$sql = 'SELECT nom, couleur, calories
    FROM fruit
WHERE calories < :calories AND couleur = :couleur';
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':calories' => 150, ':couleur' => 'red'));
$red = $sth->fetchAll();
$sth->execute(array('calories' => 175, 'couleur' => 'yellow'));
$yellow = $sth->fetchAll();
?>


Si tu lis la doc de prepare et execute :
Le problème, c'est que tu demande d'exécuter une requête en lui passant des paramètres, mais que tu la prepare sans paramètres.
Du coup, forcément ça coince !
 
Essaye d'adapter un des exemples de la doc à ton cas, et vois ce que ça donne...

Reply

Marsh Posté le 29-01-2009 à 13:28:05    

C'est encore pire si j'ajoute cela à mon prepare car la page ne s'affiche plus du tout, une page blanche c'est tout.

Reply

Marsh Posté le 30-01-2009 à 10:52:27    

Code :
  1. $sth->execute(array(':calories' => 150, ':couleur' => 'red'));

Tu as bien mis les ":" dans le execute ?

Reply

Marsh Posté le 30-01-2009 à 18:46:01    

Oui

Code :
  1. $statement->execute(array(':id_theme' => $desired_theme_id));

Reply

Marsh Posté le 05-02-2009 à 22:56:30    

Pas d'idées ? :(

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed