PHP:str_replace的问题

时间:2011-03-13 10:35:30

标签: php arrays str-replace replace

我注意到 str_replace 函数的奇怪行为。 你能告诉我为什么而不是 no_2 中的3号我得到 no_4

情况如下:

$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?

4 个答案:

答案 0 :(得分:7)

str_replace()的文档说(引用)

  

因为 str_replace()替换为左侧   对,它可能会取代以前的   执行多次时插入的值   替代品。

我相信你正是在这种情况下:

  • 由于no_2no_3数组
  • 中的第二个项,您$pattern已被替换为$change
  • 然而,由于no_3no_4数组中的 thid 项,$pattern被替换为$change / LI>


为避免出现这种情况,您可以尝试颠倒这两个数组中项目的顺序:

$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 :(得分:3)

如果您将str_replace与一系列针头一起使用,则每个针头都会在单独的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

  1. SELECT * FROM %s WHERE no_1 IN (%s) AND no_2 IN (%s) AND no_3 IN (%s)
  2. SELECT * FROM %s WHERE no_1 IN (%s) AND no_3 IN (%s) AND no_3 IN (%s)
  3. SELECT * FROM %s WHERE no_1 IN (%s) AND no_4 IN (%s) AND no_4 IN (%s)
  4. 要同时进行替换,您可以使用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"
    

答案 2 :(得分:1)

首先,你用1代替1,所以没关系

SELECT * FROM %s WHERE no_1 IN (%s) AND no_2 IN (%s) AND no_3 IN (%s)

然后,用3替换2,得到

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,你可以在以后再次替换它。

答案 3 :(得分:0)

因为一旦你用3替换2,下一次替换将总是用4替换3