首页 > 解决方案 > preg_replace - 不要替换已经替换的零件

问题描述

给定带有占位符的 SQL 查询:

SELECT * FROM table WHERE `a`=? AND `b`=?

和查询参数 ['aaa', 'bbb'],我想用相应的参数替换 ?-placeholders。所以,我这样做:

$sql = preg_replace(array_fill(0, count($params), '#\?#'), $params, $sql, 1);

(在这个问题中,我们不专注于 mysql 转义、引用等)。

一切正常,我得到

SELECT * FROM table WHERE `a`=aaa AND `b`=bbb

但是如果我们的第一个参数看起来像这样:“?aa”,一切都会失败:

SELECT * FROM table WHERE `a`=bbba AND `b`=?

显然,第一次替换通过更改“a=?” 进入“a=?aa”,第二遍将这个(刚刚插入的)问号更改为“bbb”。

问题是:如何绕过这种令人困惑的 preg_replace 行为?

标签: phppreg-replace

解决方案


您可以使用preg_replace_callback$params每次替换使用一个项目。

$sql = 'SELECT * FROM table WHERE `a`=? AND `b`=?';
var_dump('Original: ' . $sql);
$params=['aaa','bbb'];

$sql = preg_replace_callback("/\\?/",function($m) use (&$params) {
    return array_shift($params);
}, $sql);

var_dump('Result: ' . $sql);

让我知道


推荐阅读