2010-08-24 19 views
5

Estoy tratando de entender la diferencia entre mysqli's query() y prepare(). Tengo código como a continuación, y me gustaría obtener los mismos resultados de ambos. Sin embargo, la preparación() no funciona como se esperaba. ¿por qué?prepare() vs query() mysqli

// this works 

    if ($query = $this->db->query("SELECT html FROM static_pages WHERE page = 'cities'")) { 

    $result = $query->fetch_row(); 
    echo $result[0]; 

    $query->close(); 

    } 

    //this does not work 
    //result is empty 

    $cities = 'cities'; 

    $stmt = $this->db->prepare("SELECT html FROM static_pages WHERE page = ?"); 
    $stmt -> bind_param("s", $cities); 
    $stmt->execute(); 
    $stmt->bind_result($result); 
    $stmt->fetch(); 
    echo $result; 
    $stmt->close(); 

    $this->db->close(); 

estos son mis configuraciones de servidor conforme a lo solicitado:

OS

Vista 64bit/PHP versión 5.2.9

mysqli

Mysqli apoyo permitió

API de cliente de biblioteca versión 5.0.51a

API del cliente de la versión 5.0.51a cabecera

MYSQLI_SOCKET /tmp/mysql.sock

Directiva local Valor Valor Maestro

mysqli. default_host ningún valor sin valor

mysqli.default_port 3306 3306

mysqli.default_pw ningún valor sin valor

mysqli.default_socket ningún valor sin valor

mysqli.default_user ningún valor sin valor

mysqli.max_links Ilimitado Ilimitado

mysqli.reconnect Off Off

+0

tiene que imprimir $ stmt-> error() para ver qué está pasando mal. –

+0

Ah, perdón, moi, es una variable, no un método. $ stmt-> error –

+0

En ese caso, $ stmt-> error no tiene ningún valor. Lo intenté en todas las líneas. – Mike

Respuesta

2

Se puede tratar $stmt->store_result(); entre $stmt->execute(); y $stmt->bind_result($result);?

+0

QUE HACE EL TRUCO. Ahora a estudiar, store_results(). Muchas gracias. Soy nuevo en el mysqli, tratando de entenderlo. – Mike

+0

Buscar más detalles: http://us3.php.net/manual/en/mysqli-stmt.store-result.php .Btw, si sirve, me gustaría obtener un '+' – a1ex07

+0

De un lado nota, hace que te preguntes por qué bind_result no fue suficiente. – Mike

0

Debe ser echo $result; no

+0

Vaya, eso es un error, pero no la razón por la que esto no funciona. Lo arreglé en el código en vivo y aún así vuelve vacío. – Mike

+0

@Mike por la razón que tiene que preguntarle a su programa, no a las personas que no tienen idea de lo que está sucediendo. No tengo un intérprete de PHP en mi cabeza para ejecutar tu código y ver el resultado. Tienes que hacerlo tú mismo. Sin ofender, es la única forma. –

+0

Bueno, el hecho de que query() funcione y prepare() no, a pesar de que tienen los mismos datos exactos, debería decirte algo. Son esas dos funciones no intercambiables, en el sentido del código que tengo arriba. – Mike

2

Cualquier de las funciones mysqli_ * puede fallar. En este caso, el valor de retorno es false y las propiedades error/errno del objeto mysqli o mysqli_stmt contienen más información sobre el error. La secuencia de comandos tiene que probar todos y cada uno de los valores devueltos y reaccionar adecuadamente en caso de error (por ejemplo, no tiene sentido preparar la instrucción si la conexión falló).

<?php 
$foo = new Foo; 
$foo->init(); 
$foo->bar(); 
class Foo { 
    public function bar() { 
    $cities = 'cities'; 
    $stmt = $this->db->prepare("SELECT html FROM soTest WHERE page = ?"); 
    if (!$stmt) { 
     echo "prepare failed\n"; 
     echo "error: ", $this->db->error, "\n"; 
     return; 
    } 

    $rc = $stmt->bind_param("s", $cities); 
    if (!$rc) { 
     echo "bind_param failed\n"; 
     echo "error: ", $stmt->error, "\n"; 
     return; 
    } 

    $rc=$stmt->execute(); 
    if (!$rc) { 
     echo "execute failed\n"; 
     echo "error: ", $stmt->error, "\n"; 
     return; 
    } 

    $rc = $stmt->bind_result($result); 
    if (!$rc) { 
     echo "bind_result failed\n"; 
     echo "error: ", $stmt->error, "\n"; 
     return; 
    } 

    $rc = $stmt->fetch(); 
    if (!$rc) { 
     echo "no such record\n"; 
    } 
    else { 
     echo 'result: ', $result, "\n"; 
    } 
    $stmt->close(); 
    } 

    public function init() { 
    $this->db = new mysqli('localhost', 'localonly', 'localonly', 'test'); 
    if ($this->db->connect_error) { 
     die('connection failed: ' . $this->db->connect_error); 
    } 
    $rc = $this->db->query('CREATE TEMPORARY TABLE 
     soTest (id int auto_increment, html varchar(16), page varchar(16),primary key(id))' 
    ); 
    if (!$rc) { die('error: '.$this->db->error); } 
    $rc = $this->db->query("INSERT INTO soTest (html,page) VALUES ('htmlFoo','foo'),('htmlCities','cities')"); 
    if (!$rc) { die('error: '.$this->db->error); } 
    } 
} 

Tenga en cuenta CWE-209: Information Exposure Through an Error Message. Imprimir el mensaje de error real en mi script de ejemplo es solo para probar. Y puede usar un manejo de errores un poco más sofisticado que solo die().