2009-12-29 13 views
8

Todos los ejemplos que veo usando mysqli_fetch_object usan mysql_query(), no puedo hacerlo funcionar con declaraciones preparadas. ¿Alguien sabe qué está mal con este fragmento de código, ya que fetch_object devuelve null?¿Es posible usar mysqli_fetch_object con una instrucción preparada?

$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 salida es:

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

filas Seguramente num deben ser> 0 si está esperando un objeto no nulo que ser devueltos? – jcuenod

Respuesta

0

No creo que la interfaz funciona de esa manera.

Pasando por la documentación y los ejemplos (http://www.php.net/manual/en/mysqli.prepare.php) parece que $ stmt-> execute() no devuelve un conjunto de resultados, sino un booleano que indica éxito/falla (http://www.php.net/manual/en/mysqli-stmt.execute.php). Para obtener realmente el resultado, debe vincular las variables al conjunto de resultados (después de la llamada de ejecución) utilizando $ stmt-> bind_result (http://www.php.net/manual/en/mysqli-stmt.bind-result.php).

Después de hacer todo eso, puede hacer llamadas repetidas a $ stmt-> fetch()() para completar las variables enlazadas con los valores de columna de la fila actual. No veo ninguna mención de $ stmt-> fetch_object() ni veo cómo esa interfaz podría funcionar con un esquema de vinculación variable como se describe.

Así que esta es la historia de la obtención de resultados "normales" de las declaraciones preparadas de mysqli.

En su código, hay algo que sospecho que es un error, o al menos no estoy seguro de que tenga la intención de hacerlo. Te cola:

$result = $stmt->result_metadata(); 

assignes los metadatos de resultados, que a su vez se representa como un conjunto de resultados, a la variable $ resultado. De acuerdo con el documento (http://www.php.net/manual/en/mysqli-stmt.result-metadata.php), solo puede usar un subconjunto de los métodos en estos tipos 'especiales' de conjuntos de resultados, y fetch_object() no es uno de ellos (al menos no se menciona explícitamente).

Quizás sea un error que fetch_object() no esté implementado para estos resultados de metadatos, quizás deba presentar un error al bugs.mysql.com al respecto.

+0

Quiero usar fetch_object para no tener que definir una clase y vincular explícitamente las variables miembro. Trataré de crear mi propio fetch_object para las declaraciones preparadas. – BeWarned

11

Este es el código que uso para crear un objeto a partir de una declaración preparada.
¿Podría quizás ser utilizado en una subclase 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

Gracias, terminé haciendo algo como su código – BeWarned

7

MySql extensión controlador nativo (mysqlnd), tiene la get_result método:

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

Esta es una buena solución; te permite recuperar los resultados estilo OO con '$ obj-> nombre_del_db_db;' etc., exactamente lo que estaba buscando, gracias. – Timmy

+2

advertencia: Esto solo funciona si está usando el controlador 'mysqlnd' – Populus

+0

@Populus gracias, agregado en el cuerpo de la respuesta. – T30

Cuestiones relacionadas