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
*/