如何递归搜索和替换未知深度多维 PHP 数组中的值?
How can I recursively search for and replace values inside of an unknown-depth multidimensional PHP array?
我正在使用 JSON 字符串。我将其转换为关联数组以查找特定值并在找到特定键时更改这些值 (['content'])。数组的深度总是未知的,并且总是变化的。
这是我写的函数。它采用一个数组作为参数并通过引用传递它,以便修改变量本身而不是在该函数的本地范围内的副本。
$json_array = json_decode($json_string, true);
function replace_data(&$json_array, $data='REPLACE TEST')
{
foreach($json_array as $key => $value) {
if ($key == 'content' && !is_array($value)) {
$json_array[$key] = $data;
} else {
if (is_array($value)) {
replace_data($value, $data);
}
}
}
}
replace_data($json_array, "test test test");
var_dump($json_array);
我希望发生的情况是,无论在什么深度,每次找到键 ['content'] 时,它都会替换为 $data 参数中指定的值。
但是,当我 var_dump($json_array)
这些值没有改变。
我错过了什么?
要扩展我的评论,您需要此处的另一个参考:
foreach($json_array as $key => &$value) {
这样,当您进行递归调用时,将传递对原始值的引用,而不是使用 foreach
循环创建的本地副本。
来自PHP manual entry for foreach
:
In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference.
您还会在手册中看到它建议在循环后取消设置对 $value
的引用。尽管如果您不在函数中这样做可能不会造成任何问题,但最好养成总是取消设置在 foreach
循环中创建的引用的习惯。如果你不这样做,它可能会导致一些 strange looking problems。
function replace_data($json_array, $data = 'REPLACE TEST') {
array_walk_recursive($json_array, function (&$value, $key) use ($data) {
if (!is_array($value) && $key === 'content') {
// $value passed by reference
$value = $data;
}
});
return $json_array;
}
并且没有引用:
function replace_data($json_array, $data = 'REPLACE TEST') {
foreach ($json_array as $key => $value) {
if (is_array($value)) {
$json_array[$key] = replace_data($value, $data);
} elseif ($key === 'content') {
$json_array[$key] = $data;
}
}
return $json_array;
}
从 PHP7.4 开始,“箭头函数”语法提供了一种简洁的方法。
随着叶子节点的迭代,如果key是content
,则替换text,否则不改变value。
没有 return
被使用。所有突变都直接应用于以 &
.
为前缀的传入变量
function replace_data(&$array, $replaceWith = 'REPLACE TEST')
{
array_walk_recursive(
$array,
fn(&$v, $k) => $v = ($k === 'content' ? $replaceWith : $v)
);
}
replace_data($json_array, "test test test");
var_export($json_array);
我正在使用 JSON 字符串。我将其转换为关联数组以查找特定值并在找到特定键时更改这些值 (['content'])。数组的深度总是未知的,并且总是变化的。
这是我写的函数。它采用一个数组作为参数并通过引用传递它,以便修改变量本身而不是在该函数的本地范围内的副本。
$json_array = json_decode($json_string, true);
function replace_data(&$json_array, $data='REPLACE TEST')
{
foreach($json_array as $key => $value) {
if ($key == 'content' && !is_array($value)) {
$json_array[$key] = $data;
} else {
if (is_array($value)) {
replace_data($value, $data);
}
}
}
}
replace_data($json_array, "test test test");
var_dump($json_array);
我希望发生的情况是,无论在什么深度,每次找到键 ['content'] 时,它都会替换为 $data 参数中指定的值。
但是,当我 var_dump($json_array)
这些值没有改变。
我错过了什么?
要扩展我的评论,您需要此处的另一个参考:
foreach($json_array as $key => &$value) {
这样,当您进行递归调用时,将传递对原始值的引用,而不是使用 foreach
循环创建的本地副本。
来自PHP manual entry for foreach
:
In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference.
您还会在手册中看到它建议在循环后取消设置对 $value
的引用。尽管如果您不在函数中这样做可能不会造成任何问题,但最好养成总是取消设置在 foreach
循环中创建的引用的习惯。如果你不这样做,它可能会导致一些 strange looking problems。
function replace_data($json_array, $data = 'REPLACE TEST') {
array_walk_recursive($json_array, function (&$value, $key) use ($data) {
if (!is_array($value) && $key === 'content') {
// $value passed by reference
$value = $data;
}
});
return $json_array;
}
并且没有引用:
function replace_data($json_array, $data = 'REPLACE TEST') {
foreach ($json_array as $key => $value) {
if (is_array($value)) {
$json_array[$key] = replace_data($value, $data);
} elseif ($key === 'content') {
$json_array[$key] = $data;
}
}
return $json_array;
}
从 PHP7.4 开始,“箭头函数”语法提供了一种简洁的方法。
随着叶子节点的迭代,如果key是content
,则替换text,否则不改变value。
没有 return
被使用。所有突变都直接应用于以 &
.
function replace_data(&$array, $replaceWith = 'REPLACE TEST')
{
array_walk_recursive(
$array,
fn(&$v, $k) => $v = ($k === 'content' ? $replaceWith : $v)
);
}
replace_data($json_array, "test test test");
var_export($json_array);