2010-01-23 19 views
5

Sto riscontrando un problema con l'oggetto PDO di PHP per preparare una dichiarazione di aggiornamento e aggiornare il record. Ho preso la query SQL raw e l'ho eseguita in phpMyAdmin con i parametri sostituiti dai loro valori passati alla funzione. Che aggiorna il record come previsto. Tuttavia, quando viene eseguito dallo script, non viene aggiornato. Genera zero errori e restituisce una risposta errorInfo() di 00000, che a mio modo di vedere è il modo in cui DOP dice che tutto va bene. So che l'oggetto PDO funziona perché inserisce e seleziona correttamente i record dal database, compreso quello che sto tentando di aggiornare. Capisco che questa funzione di aggiornamento sia brutta, sto solo imparando DOP.PHP PDO query richiesta non aggiornata record

Ovviamente, questo è codificato in PHP5, usando PDO.

Classe Funzione:

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

chiamato dallo script sessione di aggiornamento/login:

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

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

uscita da echi e print_r in funzione della classe e del chiamante:

// 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 
) 

risposta

2

I don' So molto di PDO, ma la mia sensazione è che ci sia qualcosa di sbagliato nel modo in cui si legano i parametri. Tuttavia, il modo più semplice per dirlo è vedere la query effettiva.

Secondo lo docs, dovresti essere in grado di visualizzare la query generata mentre passava a SQL in $stmt->queryString. Al momento non è possibile vedere perché i parametri sono vincolati alla dichiarazione dopo lo che stai emettendo $stmt.

fare un print_r() dopo aver associare i parametri (o forse anche dopo l'esecuzione della query, non lo so). Dovresti ottenere la stringa di query vera e arrivare alla fine del problema.

+0

Ho incluso la stringa di query nella domanda originale. [queryString] => aggiorna gli utenti impostano 'twitter_key' = ': twitter_key',' twitter_secret' = ': twitter_secret' dove id = ': id' LIMIT 1; tuttavia, solo per essere al 100% che stiamo ottenendo il queryString finale che posso vedere io seguito le istruzioni ed i risultati restituire la stessa stringa: queryString: gli utenti Aggiornare Imposta 'twitter_key' = ': twitter_key',' twitter_secret' = ': twitter_secret' dove id = ': id' LIMIT 1; che corrisponde anche al ritorno da $ stmt-> debugDumpParams() – Jayrox

+0

No, questa è la query non elaborata, non è vero? In realtà non stai inviando il valore ': twitter_key' al database? Non avrebbe senso, vero? –

+0

è corretto, fa un po 'di magia e cambia: twitter_key al valore. Non so come farlo stampare la query con i valori passati o anche se è effettivamente possibile. – Jayrox

1

Corretta funzione di classe che funziona ... Inserita qui nel caso in cui qualcuno lo desideri, da cui imparare, da usare o da sempre.

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