2010-01-23 15 views
5

Ich habe ein Problem mit PHP-PDO-Objekt, um eine Update-Anweisung vorzubereiten und den Datensatz zu aktualisieren. Ich habe die rohe SQL-Abfrage genommen und sie in phpMyAdmin ausgeführt, wobei die Parameter durch ihre Werte ersetzt wurden, die an die Funktion übergeben wurden. Das aktualisiert den Datensatz wie beabsichtigt. Wenn es jedoch vom Skript ausgeführt wird, wird es nicht aktualisiert. Es wirft Null Fehler und es gibt eine errorInfo() Antwort von 00000 zurück, was meines Wissens nach PDO's Art zu sagen alles gut ist. Ich weiß, dass das PDO-Objekt funktioniert, da es Datensätze erfolgreich aus der Datenbank einfügt und auswählt, einschließlich desjenigen, den ich zu aktualisieren versuche. Ich verstehe diese Update-Funktion ist hässlich, ich lerne gerade PDO.PHP PDO Vorbereitete Anweisung Abfrage nicht aktualisieren Datensatz

Offensichtlich ist dies in PHP5 mit PDO codiert.

Klasse Funktion:

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

Called von Sitzung Update/Anmeldeskript:

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

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

Ausgabe von echos und print_r in Klassenfunktion und Anrufer:

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

Antwort

2

I don‘ Ich weiß viel über PDO, aber ich habe das Gefühl, dass etwas mit der Art und Weise, wie man die Parameter bindet, nicht stimmt. Am einfachsten ist es jedoch, die tatsächliche Abfrage zu sehen.

Nach der docs sollten Sie in der Lage sein, die generierte Abfrage zu sehen, wie es an SQL in $stmt->queryString ging. Es ist nicht möglich, sofort zu sehen, da Sie die Parameter an die Anweisung binden, nachdem Sie $stmt ausgegeben haben.

Tun Sie eine print_r() nachdem Sie die Parameter binden (oder vielleicht sogar nach der Ausführung der Abfrage, weiß ich nicht). Sie sollten die echte Abfragezeichenfolge abrufen und das Problem auf den Grund bringen.

+0

Ich habe die Abfragezeichenfolge in die ursprüngliche Frage aufgenommen. [queryString] => Benutzer aktualisieren set 'twitter_key' =': twitter_key ', 'twitter_secret' =': twitter_secret 'wobei id =': id 'LIMIT 1; aber, um 100% zu sein, bekommen wir den final queryString, den ich sehen kann Ich folgte Ihren Anweisungen und die Ergebnisse geben den gleichen String zurück: queryString: Benutzer aktualisieren Set 'twitter_key' = ': twitter_key',' twitter_secret' = ': twitter_secret' wobei id = ': id' LIMIT 1; , die auch die Rückkehr von $ stmt-> debugDumpParams() – Jayrox

+0

Nein, das ist die unverarbeitete Abfrage, nicht wahr? Sie senden den Wert ': twitter_key' nicht wirklich an die Datenbank? Das würde keinen Sinn ergeben, oder? –

+0

das ist richtig, es macht etwas Magie und ändert den: twitter_key auf den Wert. Ich weiß nicht, wie man die Abfrage mit den übergebenen Werten druckt oder ob es tatsächlich möglich ist. – Jayrox

1

Korrigierte Klassenfunktion, die funktioniert ... Platziert für den Fall, dass jemand es möchte, von oder zu lernen oder zu verwenden.

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