Search code examples
phpjsonrecursionmultidimensional-arraypass-by-reference

How can I recursively search for and replace values inside of an unknown-depth multidimensional PHP array?


I'm working with a JSON string. I'm converting it to an associative array to find specific values and change those values when a certain key is found (['content']). The depth of the array is always unknown and will always vary.

Here is the function I wrote. It takes an array as an argument and passes it by reference so that the variable itself is modified rather than a copy of it scoped locally to that function.

$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);

What I'm expecting to happen is every time a key ['content'] is found at no matter what depth, it replaces with that value specified in the $data argument.

But, when I var_dump($json_array) Those values are unchanged.

What am I missing?


Solution

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

    And without references:

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