Если вы используете 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
:
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);
}
Я использовал анонимную функцию в этом примере, ноон также будет работать с create_function
.
При этом порядок замены не имеет значения.Вы даже можете обменять два значения:
var_dump(str_replacep(array(1,2), array(2,1), "12")); // string(2) "21"