2010-01-23 7 views
5

Tengo un problema al utilizar el objeto PDO de PHP para preparar una declaración de actualización y actualizar el registro. He tomado la consulta SQL sin procesar y la ejecuté en phpMyAdmin con los parámetros reemplazados por sus valores que se pasan a la función. Que actualiza el registro como se pretendía. Sin embargo, cuando se ejecutó desde el script, no se actualiza. Lanza cero errores y devuelve una respuesta errorInfo() de 00000, que a mi entender es la forma en que PDO dice que todo está bien. Sé que el objeto PDO funciona porque inserta y selecciona con éxito los registros de la base de datos, incluido el que estoy tratando de actualizar. Entiendo que esta función de actualización es fea, solo estoy aprendiendo PDO.PHP PDO Consulta de declaración preparada que no actualiza el registro

Obviamente, esto está codificado en PHP5, usando PDO.

Clase Función:

public function update($tbl_name, $where = null, $what = null) 
    { 
     if(is_array($where)) 
     { 
      $where_str = 'where '; 
      foreach($where as $key => $val) 
      { 
       $where_str .= "{$key} = ':{$key}' and "; 
      } 
      $where_str = substr($where_str,0,-5); 

      $what_str = 'set '; 
      foreach($what as $key => $val) 
      { 
       $what_str .= "`{$key}` = ':{$key}', "; 
      } 
      $what_str = substr($what_str,0,-2); 

      $query_str = "update {$tbl_name} {$what_str} {$where_str} LIMIT 1;"; 
      $stmt = $this->dbh->prepare($query_str); 
      echo '<pre>'.print_r($stmt, true).'</pre>'; 
      foreach($what as $key => $val) 
      { 
       if('date_time' === $key) continue; 
       $bind = $stmt->bindValue(":{$key}",$val); 
       echo ($bind ? 'true' : 'false')." :{$key}=",$val,'<br/>'; 
      } 
      foreach($where as $key => $val) 
      { 
       if('date_time' === $key) continue; 
       $bind = $stmt->bindValue(":{$key}",$val); 
       echo ($bind ? 'true' : 'false')." :{$key} ",$val,'<br/>'; 
      } 
     }else{ 
      return false; 
     } 
     $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     $exec = $stmt->execute(); 
     echo 'exec: '.($exec === true ? 'true:' : 'false:').':'.$exec.'<br/>'; 

     echo '<pre>'; 
     $stmt->debugDumpParams(); 
     echo '</pre>'; 

     return $stmt->errorInfo(); 
    } 

Llamado desde el guión sesión de actualización/entrada:

$where = array(
    'id' => $user['id'], 
    ); 
$what = array(
    'twitter_key' => $oauth_token, 
    'twitter_secret' => $oauth_token_secret 
    ); 

$update = $db->update('users', $where, $what); 

salida de ecos y print_r en función de la clase y la persona que llama:

// print_r($stmt = $this->dbh->prepare($query_str)) output: 
PDOStatement Object 
(
    [queryString] => update users set `twitter_key` = ':twitter_key', `twitter_secret`  = ':twitter_secret' where id = ':id' LIMIT 1; 
) 

// output from the bing params and execution returns 
true :twitter_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXX 
true :twitter_secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
true :id 20 
exec: true:1 

// $stmt->debugDumpParams() output: 
SQL: [111] update users set `twitter_key` = ':twitter_key', `twitter_secret` = ':twitter_secret' where id = ':id' LIMIT 1; 
Params: 3 
Key: Name: [12] :twitter_key 
paramno=-1 
name=[12] ":twitter_key" 
is_param=1 
param_type=2 
Key: Name: [15] :twitter_secret 
paramno=-1 
name=[15] ":twitter_secret" 
is_param=1 
param_type=2 
Key: Name: [3] :id 
paramno=-1 
name=[3] ":id" 
is_param=1 
param_type=2 

// print_r($stmt->errorInfo()) output: 
Array 
(
    [0] => 00000 
) 

Respuesta

2

I don' Sé mucho sobre PDO, pero tengo la sensación de que hay algún problema con la forma en que se vinculan los parámetros. Sin embargo, la manera más fácil de decirlo con certeza es ver la consulta real.

De acuerdo con docs, debería poder ver la consulta generada tal como fue a SQL en $stmt->queryString. No es posible verlo ahora porque está vinculando los parámetros a la instrucción después de está produciendo $stmt.

Haz un print_r() después de vincular los parámetros (o tal vez incluso después de la ejecución de la consulta, no sé). Debería obtener la cadena de consulta real y llegar al fondo del problema.

+0

Incluí la cadena de consulta en la pregunta original. [queryString] => actualizar usuarios establecer 'twitter_key' = ': twitter_key',' twitter_secret' = ': twitter_secret' donde id = ': id' LIMIT 1; sin embargo, solo para ser 100% estamos obteniendo la última queryString que puedo ver. Seguí tus instrucciones y los resultados devuelven la misma cadena: queryString: actualizar usuarios establecer 'twitter_key' = ': twitter_key',' twitter_secret' = ': twitter_secret' donde id = ': id' LIMIT 1; que también coincide con el retorno de $ stmt-> debugDumpParams() – Jayrox

+0

No, esa es la consulta no procesada, ¿no es así? En realidad, ¿no estás enviando el valor ': twitter_key' a la base de datos? Eso no tendría sentido, ¿verdad? –

+0

eso es correcto, hace algo de magia y cambia el: twitter_key al valor. No sé cómo hacer que se imprima la consulta con los valores aprobados o incluso si es posible. – Jayrox

1

Función de clase corregida que funciona ... Colocada aquí en caso de que a alguien le guste, para aprender, usar o lo que sea.

public function update($tbl_name, $where = null, $what = null) 
    { 
     if(is_array($where) && is_array($what)) 
     { 
      $where_str = 'where '; 
      foreach($where as $key => $val) 
      { 
       $where_str .= "{$key} = :{$key} and "; 
      } 
      $where_str = substr($where_str,0,-5); 

      $what_str = 'set '; 
      foreach($what as $key => $val) 
      { 
       $what_str .= "{$key} = :{$key}, "; 
      } 
      $what_str = substr($what_str,0,-2); 

      $query_str = "update {$tbl_name} {$what_str} {$where_str} LIMIT 1;"; 
      $stmt = $this->dbh->prepare($query_str); 
      foreach($what as $key => $val) 
      { 
       if('date_time' === $key) continue; 
       $bind = $stmt->bindValue(":{$key}",$val); 
      } 
      foreach($where as $key => $val) 
      { 
       if('date_time' === $key) continue; 
       if('id' === $key) 
       { 
        $bind = $stmt->bindValue(":{$key}",$val, PDO::PARAM_INT); 
       }else{ 
        $bind = $stmt->bindValue(":{$key}",$val); 
       } 
      } 
     }else{ 
      return false; 
     } 
     $stmt->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     $exec = $stmt->execute(); 
     return $stmt->errorInfo(); 
    } 
Cuestiones relacionadas