【问题标题】:How can I recursively search for and replace values inside of an unknown-depth multidimensional PHP array?如何递归搜索和替换未知深度多维 PHP 数组中的值?
【发布时间】:2017-05-09 08:44:55
【问题描述】:

我正在使用 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) 时,这些值没有改变。

我错过了什么?

【问题讨论】:

  • 需要更多参考资料。
  • 不确定你的意思。 PHP 手册页指出“仅函数定义就足以通过引用正确传递参数。”我会在哪里添加更多参考? php.net/manual/en/language.references.pass.php
  • 引用通常会使代码复杂化,最好避免它们。
  • 对不起,简短的评论。我有点想寻找一个微妙的“更多牛铃”参考。希望我的回答能说明我在说什么。
  • 我的备用意见关于避免引用,因为它们使代码复杂化,最好不要过度使用它们,但任何事情都是如此, 真的。它们通常是使用您的代码完成任务的一种完全有效的方式,您在这里的使用对我来说似乎是合理的。没有冒犯的意思,@Timurib。就像我说的,只是我的看法。

标签: php json recursion multidimensional-array pass-by-reference


【解决方案1】:

要扩展我的评论,您需要在这里提供另一个参考:

foreach($json_array as $key => &$value) {

这样,当您进行递归调用时,会传递对原始值的引用,而不是使用 foreach 循环创建的本地副本。

来自PHP manual entry for foreach

为了能够直接修改循环内的数组元素,在 $value 之前加上 &。在这种情况下,该值将通过引用分配。

您还会在手册中看到它建议在循环后取消对$value 的引用。即使在函数中不这样做可能不会导致任何问题,但最好养成始终取消设置在 foreach 这样的循环中创建的引用的习惯。如果你不这样做,它可能会导致一些strange looking problems

【讨论】:

    【解决方案2】:

    array_walk_recursive:

    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;
    }
    

    【讨论】:

    • 我同意 array_walk_recursive 非常适合这个。
    猜你喜欢
    • 2015-06-30
    • 1970-01-01
    • 2010-11-07
    • 2017-07-03
    • 2020-09-24
    • 1970-01-01
    • 2014-06-21
    • 2011-12-14
    • 2013-11-30
    相关资源
    最近更新 更多