【发布时间】:2014-10-11 01:33:22
【问题描述】:
在我们的 Web 应用程序中,我们有一个类可以模拟准备好的语句以正确转义 SQL 参数。
现在,我现在最好只使用PDO,但应用程序很旧,重构可能会很长,所以我暂时只想修复我发现的一个错误。
考虑使用我们的类的这段代码:
$s = Q()->statement("SELECT * FROM DUAL WHERE 1 = :a AND 2 = :b AND 3 = :c");
$s->bindValue('c', ':b');
$s->bindValue('b', ':a');
$s->bindValue('a', ':c');
var_dump($s->prepared);
第一行创建语句,然后绑定一些值,然后我转储准备好的语句。
这样的结果如下:
SELECT * FROM DUAL WHERE 1 = ':c' AND 2 = '':c'' AND 3 = ''':c'''
这是因为从最后一个参数到第一个参数一次替换一个。
我也尝试在单个函数调用中进行替换,使用带有数组参数的str_replace(),但无济于事。
所以我想知道是否有办法让这个操作以某种方式“原子化”,这样如果占位符值是另一个有效的占位符,它就不会被替换。
编辑:
这是我的班级的替换方法:
protected function prepare() {
if (!$this->db) {
trigger_error (__METHOD__ . ': no Connection available to properly quote the value', E_USER_WARNING);
return false;
}
$this->prepared = str_replace(
array_map(array($this, 'getPlaceholderName'), array_keys($this->params)),
array_map(array($this->db, 'quote'), array_values($this->params)),
$this->original
);
return true;
}
【问题讨论】:
-
bindValue只是在内部参数数组中插入一个key => 值对,它不负责字符串中的实际替换,这是通过prepare方法完成的,我将发布在我的问题中。