2009-12-29 12 views
8

Tutti gli esempi che vedo usando mysqli_fetch_object utilizzano mysql_query(), non riesco a farlo funzionare con istruzioni preparate. Qualcuno sa cosa c'è di sbagliato con questo snippet di codice, come fetch_object restituisce null.È possibile utilizzare mysqli_fetch_object con una dichiarazione preparata

$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(); 

L'output è:

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

righe Sicuramente num dovrebbe essere> 0 se vi aspettate un oggetto non nulla da restituire? – jcuenod

risposta

0

Non credo l'interfaccia funziona così.

Passando dalla documentazione e dagli esempi (http://www.php.net/manual/en/mysqli.prepare.php) sembra che $ stmt-> execute() non restituisca un gruppo di risultati, ma un valore booleano che indica l'esito positivo/negativo (http://www.php.net/manual/en/mysqli-stmt.execute.php). Per ottenere effettivamente il risultato, è necessario associare le variabili al gruppo di risultati (dopo la chiamata di esecuzione) utilizzando $ stmt-> bind_result (http://www.php.net/manual/en/mysqli-stmt.bind-result.php).

Dopo aver fatto tutto ciò, è possibile effettuare chiamate ripetute a $ stmt-> fetch()() per riempire le variabili associate con i valori della colonna dalla riga corrente. Non vedo alcuna menzione di $ stmt-> fetch_object() né vedo come quell'interfaccia possa funzionare con uno schema di binding variabile come descritto.

Quindi questa è la storia per il recupero di risultati "normali" da mysqli preparati.

Nel tuo codice, c'è qualcosa che sospetto sia un errore, o almeno non sono sicuro che tu intendessi farlo. si allineano:

$result = $stmt->result_metadata(); 

assignes i metadati di risultati, che è rappresentata a sua volta come un gruppo di risultati, alla variabile $ result. In base al documento (http://www.php.net/manual/en/mysqli-stmt.result-metadata.php) è possibile utilizzare solo un sottoinsieme dei metodi su questi tipi "speciali" di gruppi di risultati e fetch_object() non è uno di questi (almeno non è elencato esplicitamente).

Forse è un bug che fetch_object() non è implementato per questi set di metadati, forse dovresti presentare un bug su bugs.mysql.com.

+0

Voglio usare fetch_object in modo da non dover definire una classe e associare esplicitamente le variabili membro. Proverò a creare il mio fetch_object per le istruzioni preparate. – BeWarned

11

Questo è il codice che utilizzo per creare un oggetto da un'istruzione preparata.
Potrebbe forse essere usato in una sottoclasse di 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

Grazie, ho finito per fare qualcosa proprio come il tuo codice – BeWarned

7

MySql estensione Native Driver (mysqlnd), ha il metodo get_result:

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

Questa è una bella soluzione; ti permette di recuperare lo stile OO dei risultati con '$ obj-> db_field_name;' etc, esattamente quello che stavo cercando, grazie. Avviso – Timmy

+2

: funziona solo se si utilizza il driver 'mysqlnd' – Populus

+0

@Populus, aggiunto nel corpo della risposta. – T30

Problemi correlati