【问题标题】:Atomic string replacement in PHPPHP中的原子字符串替换
【发布时间】: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 方法完成的,我将发布在我的问题中。

标签: php sql string replace


【解决方案1】:

您可能希望通过数组签名单次调用古老的strtr()

字符串 strtr ( 字符串 $str , 数组 $replace_pairs )

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

【讨论】:

  • strtr 不只适用于单个字符吗?
【解决方案2】:

这是您要使用的代码:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-05
    • 2012-04-03
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多