我有这个PDO包装器
private function cleanup($bind) {
if(!is_array($bind)) {
if(!empty($bind))
$bind = array($bind);
else
$bind = array();
}
return $bind;
}
public function run($sql, $bind="") {
$this->sql = trim($sql);
$this->bind = $this->cleanup($bind);
$this->error = "";
array_push($this->qs, $sql);
try {
$pdostmt = $this->prepare($this->sql);
if($pdostmt->execute($this->bind) !== false) {
if(preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql))
return $pdostmt->fetchAll(PDO::FETCH_ASSOC);
elseif(preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql))
return $pdostmt->rowCount();
}
} catch (PDOException $e) {
$this->error = $e->getMessage();
$this->debug();
return false;
}
}
自从几年前我开始使用它以来,我没有遇到任何问题,现在我收到一条错误消息,因为字符串没有被转义。也许我从未使用过这样的场景。
这是导致问题的SQL语句
$db->run("SELECT region_id FROM region WHERE name = '$name'");
其中$name
是霍克湾。我的印象是PDO逃脱了字符串,似乎我错了。我有什么想法可以解决这个问题吗?
答案 0 :(得分:3)
有2个错误的假设引导你回答这个问题
不幸的是,这两种假设都是错误的。
事实上,仅为SQL字符串转义 。它与PDO,准备好的陈述,安全等无关。一旦你要将字符串文字放入查询中 - 它必须转义特殊字符 但是一旦你不是 - 没有逃脱会是好事。
关于PDO,您希望它不会“逃避”,而是在查询中处理占位符。这就是整个事情的运作方式。 使用占位符,您可以正确地告知PDO 格式化相应的值。虽然这种格式化不仅涉及逃避,还涉及更多不同的措施。
所以,它必须是这样的
$db->run("SELECT region_id FROM region WHERE name = :name", array(':name' => $name));
这样,PDO会将$ name视为字符串,并相应地格式化。
虽然我不确定“清理”功能是否正常工作以及为何使用它。
答案 1 :(得分:0)
默认情况下,如果您使用普通查询而不是预准备语句,则PDO不会引用任何内容。但是您可以使用PDO::quote()
方法来转义单个值。查看更多http://www.php.net/manual/en/pdo.quote.php