Intereting Posts
Почему date () работает в два раза быстрее, если установить часовой пояс из кода? Как создать вспомогательные массивы на основе префиксов строки? Проверить код для таблицы обновления запроса Как я могу рекурсивно получить «родительский идентификатор» строк в этой таблице MySQL? понимание вложенных троичных операторов Загрузка изображения Codeigniter не работает PHP заменяет все символы звездочкой Как добавить новые поля в профиль пользователя в Drupal 7 программно Magento: администратор получает электронную почту по новому заказу страница доступа только при входе в систему с php Как заставить PHP работать снова в командной строке? Любой реальный пример слова о том, как setUp () и tearDown () следует использовать в PHPUnit? Имя пользователя и пароль не принимаются в yii2 Вы должны включить расширение openssl для загрузки файлов через https Как отслеживать время пользователя на сайте

PHP PDO: как бороться с bindValue () и зарезервированными ключевыми словами?

В моей базе данных у меня есть поля, такие как «статус» , которые являются зарезервированными ключевыми словами. Этот код отлично работает для меня ( статус экранируется ):

$sql = "UPDATE $table SET `status`='$status' WHERE `id`='123'"; 

Но теперь я хочу использовать только подготовленные заявления! Мой Database.class:

 class Database extends \PDO { private $_sth; // statement private $_sql; public function update($tbl, $data, $where, $where_params = array()) { // prepare update string and query $update_str = $this->_prepare_update_string($data); $this->_sql = "UPDATE $tbl SET $update_str WHERE $where"; $this->_sth = $this->prepare($this->_sql); // bind values to update foreach ($data as $k => $v) { $this->_sth->bindValue(":{$k}", $v); } // bind values for the where-clause foreach ($where_params as $k => $v) { $this->_sth->bindValue(":{$k}", $v); } return $this->_sth->execute(); } private function _prepare_update_string($data) { $fields = ""; foreach ($data as $k => $v) { $fields .= "`$k`=:{$k}, "; } return rtrim($fields, ", "); } } 

Пример обновления, который не будет работать:

 $DB = new Database(); $DB->update("tablename", array("status" => "active"), "`username`=:username AND `status`=:status", array("username" => "foofoo", "status" => "waiting")); 

Я думаю, это из-за ключевого слова reserverd «status». Но я не знаю, как избежать этого. Я попытался скрыть местозаполнитель в _prepare_update_string ($ data), чтобы:

 bindValue("`:{$k}`", $v) 

но результата нет.

Я надеюсь, что решение очень простое, и это просто застрявшее переполнение в моем мозгу. 😉 Спасибо заранее!

Когда вы строите строку SQL (prepare_update_string, я думаю), а также как в цикле foreach, где вы привязываете данные, запускайте увеличивающийся счетчик и добавляете его к значению привязки. Итак ": статус" станет ": status1".

Что-то вроде:

 $i = 1; foreach ($data as $k => $v) { $this->_sth->bindValue(":{$k.$i}", $v); $i++; } 

Это решит проблему любых зарезервированных ключевых слов.

Он также решает проблему (с которой я уверен, что вы столкнетесь в будущем), где вам нужно связываться с одним и тем же заполнителем более одного раза.

например, вместо следующего, который выдает ошибку из-за двух привязок на: place placeholder

 SELECT * from table WHERE `status` = :status AND `otherfield` = :status 

С увеличивающимся счетчиком это становится:

 SELECT * from table WHERE `status` = :status1 AND `otherfield` = :status2 

Наслаждаться.