Erreur critique PDO incompréhensible

Mammouth du PHP | 2937 Messages

15 mars 2007, 14:30

Salut à tous!

Pour un projet perso, j'utilise PDO pour MySQL.

En local, je n'ai aucun problème; en revanche, sur le serveur distant, j'ai droit à ce sale coup d'erreur critique:
Fatal error: Call to a member function fetchAll() on a non-object in /.../.../index.php on line 134
Voici le fichier en question:
<?php 
// Nombre de requêtes
$nombre_requetes = 0;

// Début de la génération de la page
$debut_generation = microtime (true);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Index</title>
</head>

<body id="haut">
<div id="page">
<?php 
$lang = 'fr';
require_once (dirname (__FILE__).'/conf/conf.php');
require (dirname (__FILE__).'/sgbd/pdo.php');

// Liste des forums
$requete = "SELECT id, description, titre
FROM ".VBRF_SQL_PREFIXE_TABLES."forums";
$resultat = $pdo -> query ($requete);
$donnees_forums = $resultat -> fetchAll (PDO::FETCH_ASSOC);
$nombre_requetes ++;
?>
  <table summary="Nomenclature">
    <thead>
      <tr>
        <th>&nbsp;</th>
        <th>Forums et sous-forums</th>
        <th>Sujets</th>
        <th>Messages</th>
        <th>Derniers messages</th>
      </tr>
    </thead>
    <tbody>
<?php 
if (count ($donnees_forums) == 0)
{
?>
      <tr>
        <td colspan="5">Aucun forum n'a été créé</td>
      </tr>
<?php 
}
else
{
  foreach ($donnees_forums as $forum)
  {
    // Nombre de sujets postés par forum
    $requete = "SELECT COUNT(*) AS total
FROM ".VBRF_SQL_PREFIXE_TABLES."sujets
WHERE id_forum=".$forum['id'];
    $resultat = $pdo -> query ($requete);
    $donnees = $resultat -> fetchAll ();
    $sujets = $donnees[0]['total'];
    $nombre_requetes ++;
    
    // Nombre de messages postés par forum
    $requete = "SELECT COUNT(*) AS total FROM ".VBRF_SQL_PREFIXE_TABLES."messages,
 ".VBRF_SQL_PREFIXE_TABLES."sujets
WHERE id_forum=".$forum['id'];
    $resultat = $pdo -> query ($requete);
    $donnees = $resultat -> fetchAll ();
    $messages = $donnees[0]['total'];
    $nombre_requetes ++;
    
    // Lien vers le dernier message posté par forum
    $requete = "SELECT ".VBRF_SQL_PREFIXE_TABLES."messages.id AS message,
 ".VBRF_SQL_PREFIXE_TABLES."sujets.id AS sujet,
 identifiant, titre, titre_url
FROM ".VBRF_SQL_PREFIXE_TABLES."membres,
 ".VBRF_SQL_PREFIXE_TABLES."messages,
 ".VBRF_SQL_PREFIXE_TABLES."sujets
WHERE ".VBRF_SQL_PREFIXE_TABLES."membres.id=id_membre
ORDER BY message DESC LIMIT 1";
    $resultat = $pdo -> query ($requete);
    $donnees_message = $resultat -> fetch (PDO::FETCH_ASSOC);
    $nombre_requetes ++;
?>
      <tr>
        <td><img src="themes/default/images/nouveau-message.gif" alt="Nouveaux messages" /></td>
        <td>
          <h2><a href="forum.php?forum=<?php echo $forum['id'] ?>"><?php echo $forum['titre'] ?></a></h2>
          <p><?php echo $forum['description'] ?></p>
        </td>
        <td><?php echo $sujets ?></td>
        <td><?php echo $messages ?></td>
        <td>
<?php 
    if ($sujets == 0 || $messages == 0) echo 'Pas de messages';
    else echo '<a href="sujet.php?sujet='.$donnees_message['sujet']
.'&titre='.$donnees_message['titre_url'].'#message-'.$donnees_message['message'].'">'
.$donnees_message['titre'].'</a> - Date - '.$donnees_message['identifiant'];
?>
        </td>
      </tr>
<?php 
  }
}
?>
    </tbody>
  </table>
  <div id="bas">
    <div id="statistiques">
      <h3>Statistiques</h3>
<?php 
// Nombre de membres inscrits
$requete = "SELECT COUNT(*) AS total
FROM ".VBRF_SQL_PREFIXE_TABLES."membres";
$resultat = $pdo -> query ($requete);
$donnees = $resultat -> fetchAll (); // La ligne mentionnée par l'erreur critique
$membres = $donnees[0]['total'];
$nombre_requetes ++;

// Nombre de messages
$requete = "SELECT COUNT(*) AS total
FROM ".VBRF_SQL_PREFIXE_TABLES."messages";
$resultat = $pdo -> query ($requete);
$donnees = $resultat -> fetchAll ();
$messages = $donnees[0]['total'];
$nombre_requetes ++;

// Nombre de sujets postés
$requete = "SELECT COUNT(*) AS total
FROM ".VBRF_SQL_PREFIXE_TABLES."sujets";
$resultat = $pdo -> query ($requete);
$donnees = $resultat -> fetchAll ();
$sujets = $donnees[0]['total'];
$nombre_requetes ++;
?>
      <ul>
        <li><strong><?php echo $membres ?></strong> membres sont inscrits</li>
        <li>
          <strong><?php echo $messages ?></strong> messages ont été postés
          dans <strong><?php echo $sujets ?></strong> sujets
        </li>
<?php 
// Membre le plus récent
$requete = "SELECT identifiant
FROM ".VBRF_SQL_PREFIXE_TABLES."membres
ORDER BY id DESC LIMIT 1";
$resultat = $pdo -> query ($requete);
$donnees = $resultat -> fetch (PDO::FETCH_ASSOC);
$nombre_requetes ++;
?>
        <li>Membre le plus récent&nbsp;: <a href="#haut"><?php echo $donnees['identifiant'] ?></a></li>
      </ul>
    </div>
  </div>
<?php 
// Durée de génération de la page
$fin_generation = microtime (true) - $debut_generation;
?>
  <p id="info-serveur">Requêtes effectuées&nbsp;: <?php echo $nombre_requetes ?>.
 Page générée en <?php echo round ($fin_generation, 4) ?> s.</p>
</div>
</body>
</html>
Pour info, le fichier conf (toutes les données y sont valides)
<?php 
// Configuration de la connexion à la base de données MySQL
// Adresse du serveur
define ('VBRF_SQL_ADRESSE', 'localhost');

// Utilisateur
define ('VBRF_SQL_UTILISATEUR', 'root');

// Mot de passe
define ('VBRF_SQL_MOT_DE_PASSE', '');

// Nom de la base de données
define ('VBRF_SQL_BASE', 'nom_de_la_base');

// Préfixe à ajouter devant le nom des tables
define ('VBRF_SQL_PREFIXE_TABLES', 'vbrf_');
?>
ainsi que le fichier pdo
<?php 
// Connexion au serveur de gestion de base de données et à la base de données
require_once (dirname (__FILE__).'/../conf/conf.php');
try
{
  $pdo = new PDO ('mysql:host='.VBRF_SQL_ADRESSE.
';dbname='.VBRF_SQL_BASE, VBRF_SQL_UTILISATEUR, VBRF_SQL_MOT_DE_PASSE);
}
catch (PDOException $erreur)
{
  die ('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Erreur PDO</title>
</head>

<body>
<p xml:lang="en" lang="en">'.$erreur -> getMessage ().'</p>
</body>
</html>
');
}
?>
C'est d'autant plus incompréhensible que les deux premières requêtes de type SELECT COUNT() du fichier index sont exécutées sans problème, y compris sur le serveur distant. Quant aux requêtes SQL en soi, elles ne comportent aucune erreur d'après phpMyAdmin.

Mammouth du PHP | 505 Messages

15 mars 2007, 14:45

Comme tjs avec ce genre de message, tu fais un print_r de la variable juste avant le fetchAll() et tu vas te rendre compte qu'elle ne contient pas un objet mais probablement un boolean a false car tu aura eu une erreur non testée provenant de ta query juste avant....

Mammouth du PHP | 2937 Messages

15 mars 2007, 15:20

Salut!

En local (là où tout va bien)
print_r ($requete); // Affiche SELECT COUNT(*) AS total FROM vbrf_membres
print_r ($resultat); // Affiche PDOStatement Object ( [queryString] => SELECT COUNT(*) AS total FROM vbrf_membres )
Sur le serveur distant
print_r ($requete); // Affiche SELECT COUNT(*) AS total FROM vbrf_membres
print_r ($resultat); // N'affiche rien

Mammouth du PHP | 505 Messages

15 mars 2007, 15:29

N'affiche rien c'est plutot surprenant.... Ca affiche null ou false ou qq chose, mais print_r($var) ca affiche tjs qq chose...

essai print_r('!!!' . $resultat . '!!!');

Si tu ne voie tjs rien, fait un view source html dans ton browser, parfois, le message d'erreur se trouve dans le source et n'est pas visble en htlm.

Mammouth du PHP | 2937 Messages

15 mars 2007, 15:41

Il n'y a rien d'affiché, même dans le code source.

Avec l'ajout des !!! dans le print_r(), j'obtiens en local une erreur critique ("Catchable fatal error: Object of class PDOStatement could not be converted to string") et sur le serveur distant ça n'affiche que les !!!.

Mammouth du PHP | 505 Messages

15 mars 2007, 15:54

bah catchable...


fait un bloc try catch autour des tes query() et fetchAll

avec un print_r de l'exeption

Tu peux essayer var_dump() mais je vois pas pkoi print_r n'ffiche rien si c'est bien une instance de PDO, essai aussi un echo get_class($resultat)

Mammouth du PHP | 2937 Messages

15 mars 2007, 16:26

Avec var_dump(), le schmilblick avance.
// En local
var_dump ($resultat) // Affiche object(PDOStatement)#3 (1) { ["queryString"]=> string(42) "SELECT COUNT(*) AS total FROM vbrf_membres" }

// Sur le serveur distant
var_dump ($resultat) // Affiche bool(false)

Mammouth du PHP | 505 Messages

15 mars 2007, 16:38

C'est dont bien ton $query qui ne fonctionne pas. La requete semble identiques, donc c'est probablement un pb sur la table distante

T as bien mis a jour ton fichier conf.php avec les bon login,pass etc pour le serveur distant ?

Sur le host distant, le var dump de $pdo est comment ?

Mammouth du PHP | 2937 Messages

15 mars 2007, 16:50

var_dump ($pdo) // Affiche object(PDO)#1 (0) { } en local et à distance
Il n'y a aucun problème de connexion, les requêtes précédentes sont d'ailleurs normalement exécutées.

Quant aux tables, en local je suis sous MySQL 5, à distance sous MySQL 4.0.

Et pourtant, quand je vérifie sous phpMyAdmin la requête "SELECT COUNT(*) AS total FROM vbrf_membres", rien d'anormal ne se produit.

Mammouth du PHP | 684 Messages

22 mars 2007, 10:40

J'ai le meme probleme avec PDO et Sybase, MySQL.
Tout mon projet est sous Sybase.
Je veux le faire passer a MySQL pour tester la portabilite.
J'ai exactement le meme probleme avec un select count(*).
Pour l'instant je n'ai pas encore trouver de solution car c'est plus ma priorite.
Par contre je pense a quelque chose, peut etre que PDO est mal compiler avec mes versions de MySQL.
J'avais peut etre MySQL 4 avant de compiler PHP 5 et je suis passer a la version 5 de MySQL. J'ai certainement oublier de recompiler PHP5.
Bon je cherche aussi une solution a part d'utiliser la methode de l'objet PDO pour connaitre le nombre d'element dans une table.
Zigz4g

Mammouth du PHP | 2937 Messages

22 mars 2007, 10:52

Par contre je pense a quelque chose, peut etre que PDO est mal compiler avec mes versions de MySQL.
J'avais peut etre MySQL 4 avant de compiler PHP 5 et je suis passer a la version 5 de MySQL. J'ai certainement oublier de recompiler PHP5.
Bon je cherche aussi une solution a part d'utiliser la methode de l'objet PDO pour connaitre le nombre d'element dans une table.
Vérifie ta configuration. Sous PHP 5, le module MySQL n'est pas activé par défaut. Quant à PDO pour MySQL, vérifie si l'extension est activée elle aussi.

Mammouth du PHP | 684 Messages

22 mars 2007, 11:48

J'arrive bien a faire des requetes sur mes tables mais comme toi c'est le select count(*) qui me pose probleme.
Que retourne PDO comme erreur chez toi ?
print_r($pdo->errorInfo());
Zigz4g

Mammouth du PHP | 2937 Messages

22 mars 2007, 12:12

Aux dernières nouvelles, sur le serveur distant, je n'ai plus d'erreur critique. Il faut dire aussi qu'entretemps, il y a eu une mise à jour vers la version 5.2.1 de PHP (version que j'utilise en local).