У меня возникла проблема с использованием PHP-объекта PDO для подготовки инструкции обновления и обновления записи. Я взял исходный SQL-запрос и запустил его в phpMyAdmin с замененными параметрами значениями, которые передаются функции. Что обновляет запись по своему усмотрению. Однако при запуске из скрипта он не обновляется. Он выдает нулевые ошибки и возвращает ответ errorInfo () 00000, который, насколько я понимаю, является способом PDO сказать, что все хорошо. Я знаю, что объект PDO работает, потому что он успешно вставляет и выбирает записи из базы данных, включая ту, которую я пытаюсь обновить. Я понимаю, что эта функция обновления уродлива, я просто изучаю PDO.
Очевидно, что это закодировано в PHP5, используя PDO.
Функция класса:
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(); }
Вызывается из сеанса обновления / сценария входа:
$where = array( 'id' => $user['id'], ); $what = array( 'twitter_key' => $oauth_token, 'twitter_secret' => $oauth_token_secret ); $update = $db->update('users', $where, $what);
Выход из эха и print_r в функции класса и вызывающего абонента:
// 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 )
Я мало знаю о PDO, но я чувствую, что что-то не так с тем, как вы связываете параметры. Однако самый простой способ сказать наверняка – увидеть фактический запрос.
Согласно документам , вы должны иметь возможность видеть сгенерированный запрос, когда он отправился на SQL в $stmt->queryString
. Это невозможно увидеть прямо сейчас, потому что вы связываете параметры с инструкцией после вывода $stmt
.
Сделайте print_r()
после привязки параметров (или, может быть, даже после выполнения запроса, я не знаю). Вы должны получить реальную строку запроса и дойти до сути проблемы.
Исправлена функция класса, которая работает … Размещается здесь, если кому-то это понравится, учиться, использовать или когда-либо.
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(); }