PHP中的原子字符串替换

时间:2014-08-18 07:26:00

标签: php sql string replace

在我们的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;
}

2 个答案:

答案 0 :(得分:2)

您可能希望只使用数组签名对旧的strtr()进行一次调用:

  

string strtr(string $ str,array $ replace_pairs)

当然,普通字符串替换只是一种破解,永远无法替换正确的SQL解析器,但我想你已经知道了。

答案 1 :(得分:0)

这是您要使用的代码:

$queryString = strtr($queryString, array(":a" => "b",":b"=>"c", ":c" => "a"));