I want to pass a two-dimensional array by reference with foreach
  
  
  
  Aug 25, 2020
  
  
PHP
Thing you want to do
I want to update a part of the following two-dimensional array.
$tests = [['values'=>[1,2]],['values'=>[3,4]]];
#Environment (including items not related to this work)
- MacBookPro (macOS Catalina 10.15.5)
- PHP7.4
- PHPStorm2020.2
- docker desktop2.2.0.3
- cakephp4.1.2
- xdebug2.9.6
Implementation
First, basic pass by reference
Add & to the variable used in foreach.
$tests = [1,2,3,4];
foreach ($tests as &$test) {
    if($test === 3) {
        $test = 5;
    }
}
$test = 6;
var_dump($tests);
/*
array (size=4)
  0 => int 1
  1 => int 2
  2 => int 5
  3 => int 6 ← funny
*/
In the above case, the pointer to $test remains, so if you use the same variable name after issuing foreach, the array data will be updated. Note that you need to unset it like this:
$tests = [1,2,3,4];
foreach ($tests as &$test) {
    if($test === 3) {
        $test = 5;
    }
}
unset($test);
$test = 6;
var_dump($tests);
/*
array (size=4)
  0 => int 1
  1 => int 2
  2 => int 5
  3 => int 4 ← correct
*/
There is no wondering what the specifications are.
Two-dimensional array passing by reference
Turn foreach in double.
Adding & only to the second foreach does not work.
$tests = [['values'=>[1,2]],['values'=>[3,4]]];
foreach ($tests as $test) {
    foreach ($test['values'] as &$value) {
        if($value === 2){
            $value = 5;
        }
    }
    unset($value);
}
var_dump($tests);
/*
array (size=2)
  0 =>
    array (size=1)
      'values' =>
        array (size=2)
          0 => int 1
          1 => int 2 ← funny
  1 =>
    array (size=1)
      'values' =>
        array (size=2)
          0 => int 3
          1 => int 4
*/
Adding & to both will work.
$tests = [['values'=>[1,2]],['values'=>[3,4]]];
foreach ($tests as &$test) {
    foreach ($test['values'] as &$value) {
        if($value === 2){
            $value = 5;
        }
    }
    unset($value);
}
unset($test);
/*
array (size=2)
  0 =>
    array (size=1)
      'values' =>
        array (size=2)
          0 => int 1
          1 => int 5 ← correct
  1 =>
    array (size=1)
      'values' =>
        array (size=2)
          0 => int 3
          1 => int 4
*/