PHP:问题与str_replace函数
我注意到一个str_replace函数功能的一个奇怪的行为。 你能告诉我为什么,而不是在NO_2 3号我得到no_4?PHP:问题与str_replace函数
这里的情况:
$pattern = array(1,2,3);
$change = array(1,3,4);
$sql = "SELECT * FROM %s WHERE no_1 IN (%s) AND no_2 IN (%s) AND no_3 IN (%s)";
$test_multiply[] = str_replace($pattern, $change, $sql);
其中给出:
Array ([0] => SELECT * FROM %s WHERE no_1 IN (%s) AND no_4 IN (%s) AND no_4 IN (%s))
你能告诉我该怎么办收到NO_3而不是NO_2?
的文档str_replace()
说:(引用):
因为str_replace()函数替换左到右 ,它可能会进行多次 替换时替换以前 插入值。
我相信你也正是在这种情况下:
- 你
no_2
被替换到no_3
- 在你$pattern
和$change
阵列 - 但是,由于第二项目的话,那由于您的
$pattern
和$change
ar的射线
为了避免这种情况的具体情况,你可以尝试扭转这两个数组项目的顺序:
$pattern = array(3, 2, 1);
$change = array(4, 3, 1);
而且你会得到以下结果:
SELECT * FROM %s WHERE no_1 IN (%s) AND no_3 IN (%s) AND no_4 IN (%s)
首先,您将1替换为1,这样就可以了。
SELECT * FROM %s WHERE no_1 IN (%s) AND no_2 IN (%s) AND no_3 IN (%s)
然后,更换2连3,获得
SELECT * FROM %s WHERE no_1 IN (%s) AND no_3 IN (%s) AND no_3 IN (%s)
然后用4代替3,导致 SELECT * FROM %s WHERE no_1 IN (%s) AND no_4 IN (%s) AND no_4 IN (%s)
也许你应该与另一个值(不是3)更换2,您可以稍后再进行更换。
有没有办法解决它? – elfuego1 2011-03-13 10:43:48
因为一旦你用3代替2的下一个替换将始终以4
如果使用str_replace
与针阵列代替3,每针被替换在一个单独的呼叫str_replace
。你能想象这样的事情在内部发生:
for ($i=0, $n=min(count($pattern),count($change)); $i<$n; $i++) {
$sql = str_replace($pattern[$i], $change[$i], $sql);
}
所以在第一次迭代所有1
被1
代替,那么所有2
被3
置换后,所有3
被4
取代:
SELECT * FROM %s WHERE no_1 IN (%s) AND no_2 IN (%s) AND no_3 IN (%s)
SELECT * FROM %s WHERE no_1 IN (%s) AND no_3 IN (%s) AND no_3 IN (%s)
SELECT * FROM %s WHERE no_1 IN (%s) AND no_4 IN (%s) AND no_4 IN (%s)
要做到同时更换,你可以使用preg_replace_callback
并调用映射函数对每个匹配的模式:
function str_replacep(array $search, array $replace, $subject, &$count=0) {
$combinedPattern = '/(?:'.implode('|', array_map(function($str) { return preg_quote($str, '/'); }, $search)).')/';
$map = array_combine($search, $replace);
$mapping = function($match) use ($map, $count) {
$count++;
return $map[$match[0]];
};
return preg_replace_callback($combinedPattern, $mapping, $subject);
}
我在这个例子中使用anonymous function,但它也将与create_function
工作。
有了这个替换的顺序并不重要。你甚至可以交换两个值:
var_dump(str_replacep(array(1,2), array(2,1), "12")); // string(2) "21"
好的。那么这种情况的解决方案是什么? – elfuego1 2011-03-13 10:43:06
@elfuego我已经编辑了我的答案,并提供了一个可能的解决方案 – 2011-03-13 10:43:48
这个完美正是我所需要的。非常感谢Martin! – elfuego1 2011-03-13 12:39:44