In my database I’ve fields like “status”, which are reserved keywords. This code works fine for me (status is escaped by “):
$sql = "UPDATE $table SET `status`='$status' WHERE `id`='123'";
But now I want to use prepared statements only! My 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, ", ");
}
}
Update example that won’t work:
$DB = new Database();
$DB->update("tablename",
array("status" => "active"),
"`username`=:username AND `status`=:status",
array("username" => "foofoo", "status" => "waiting"));
I think, its because of the reserverd keyword “status”. But I don’t know how to escape it. I tried to escape the placeholder in _prepare_update_string($data) to:
bindValue("`:{$k}`", $v)
but no result.
I hope the solution is very simple and it’s just a stuck overflow in my brain. 😉 Thanks in advance people!
When you construct the SQL string (prepare_update_string i think), as well as in both the foreach loops where you bind data, run an incrementing count and append it to the bind value. So “:status” become “:status1”.
Something like:
This will solve the problem of any reserved keywords.
It also solves the problem (which I’m sure you’ll encounter in the future) where you need to bind to the same placeholder more than once.
e.g. instead of the following, which throws an error due to two binds on the :status placeholder
With an incrementing count, this becomes:
Enjoy.