2009-12-29 2 views
8

Tous les exemples que je vois en utilisant mysqli_fetch_object utilisent mysql_query(), je ne peux pas l'obtenir pour travailler avec des instructions préparées. Est-ce que quelqu'un sait ce qui ne va pas avec cet extrait de code, car fetch_object renvoie null.Est-il possible d'utiliser mysqli_fetch_object avec une instruction préparée

$sql = "select 1 from dual"; 
printf("preparing %s\n", $sql); 
$stmt = $link->prepare($sql); 
printf("prepare statement %s\n", is_null($stmt) ? "is null" : "created"); 
$rc = $stmt->execute(); 
printf("num rows is %d\n", $stmt->num_rows); 
$result = $stmt->result_metadata(); 
printf("result_metadata %s\n", is_null($result) ? "is null" : "exists"); 
$rc = $result->fetch_object(); 
printf("fetch object returns %s\n", is_null($rc) ? "NULL" : $rc); 
$stmt->close(); 

La sortie est:

preparing select 1 from dual 
prepare statement created 
num rows is 0 
result_metadata exists 
fetch object returns NULL 
+0

doivent être> 0 lignes Sûrement num si vous attendez un objet non nul à retourner? – jcuenod

Répondre

0

Je ne crois pas que l'interface fonctionne comme ça. En suivant la documentation et les exemples (http://www.php.net/manual/en/mysqli.prepare.php) il semble que $ stmt-> execute() ne retourne pas un resultset, mais un booléen indiquant le succès/l'échec (http://www.php.net/manual/en/mysqli-stmt.execute.php). Pour obtenir le résultat, vous devez lier les variables au jeu de résultats (après l'appel execute) en utilisant $ stmt-> bind_result (http://www.php.net/manual/en/mysqli-stmt.bind-result.php). Après avoir fait tout cela, vous pouvez faire des appels répétés à $ stmt-> fetch()() pour remplir les variables liées avec les valeurs de colonne de la ligne courante. Je ne vois aucune mention de $ stmt-> fetch_object() et je ne vois pas comment cette interface pourrait fonctionner avec un schéma de liaison variable comme décrit.

Voici donc l'histoire de la récupération des résultats "normaux" à partir des états préparés par mysqli.

Dans votre code, il y a quelque chose que je soupçonne être une erreur, ou du moins je ne suis pas sûr que vous vouliez le faire. vous en ligne:

$result = $stmt->result_metadata(); 

assignes les métadonnées resultset, qui lui-même est représenté comme un resultset, à la variable $ result. Selon le doc (http://www.php.net/manual/en/mysqli-stmt.result-metadata.php), vous ne pouvez utiliser qu'un sous-ensemble des méthodes sur ces types de résultats spéciaux, et fetch_object() n'en fait pas partie (du moins, il n'est pas explicitement listé).

Peut-être que c'est un bug que fetch_object() n'est pas implémenté pour ces jeux de résultats de métadonnées, peut-être que vous devriez déposer un bug à bugs.mysql.com à ce propos.

+0

Je veux utiliser fetch_object pour ne pas avoir à définir une classe et lier explicitement les variables membres. Je vais essayer de créer mon propre fetch_object pour les instructions préparées. – BeWarned

11

Ceci est le code que j'utilise pour créer un objet à partir d'une instruction préparée.
Il pourrait peut-être être utilisé dans une sous-classe de mysqli?

$query = "SELECT * FROM category WHERE id = ?"; 
    $stmt = $this->_db->prepare($query); 

    $value = 1; 
    $stmt->bind_param("i", $value); 

    $stmt->execute(); 

    // bind results to named array 
    $meta = $stmt->result_metadata(); 
    $fields = $meta->fetch_fields(); 
    foreach($fields as $field) { 
     $result[$field->name] = ""; 
     $resultArray[$field->name] = &$result[$field->name]; 
    } 

    call_user_func_array(array($stmt, 'bind_result'), $resultArray); 

    // create object of results and array of objects 
    while($stmt->fetch()) { 
     $resultObject = new stdClass(); 

     foreach ($resultArray as $key => $value) { 
      $resultObject->$key = $value; 
     } 

     $rows[] = $resultObject; 
    } 

    $stmt->close(); 
+0

Merci, j'ai fini par faire quelque chose comme votre code – BeWarned

7

MySql extension pilote natif (mysqlnd), a la méthode get_result:

$stmt->execute(); 
$obj = $stmt->get_result()->fetch_object(); 
+1

Ceci est une bonne solution; vous permet de récupérer les résultats de style OO avec '$ obj-> db_field_name;' etc, exactement ce que je cherchais, merci. – Timmy

+2

avertissement: Cela ne fonctionne que si vous utilisez le pilote 'mysqlnd' – Populus

+0

@Populus merci, ajouté dans le corps de la réponse. – T30

Questions connexes