やりたいこと
以下のような二次元配列の一部を更新したい。
$tests = [['values'=>[1,2]],['values'=>[3,4]]];
環境(今回の作業に関連ないものも記載)
- MacBookPro(macOSCatalina10.15.5)
- PHP7.4
- PHPStorm2020.2
- docker desktop2.2.0.3
- cakephp4.1.2
- xdebug2.9.6
実装
まずは基本の参照渡し
foreachで利用する変数に&
を付与する。
test1.php
$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←おかしい
*/
上記だと$testへのポインタが残ったままなので、foreachを出た後に同じ変数名を利用すると、配列のデータが更新されてしまう。
以下のようにunsetする必要があることに注意。
test2.php
$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←正しい
*/
どんな仕様だよと思わなくもない。
二次元配列の参照渡し
foreachを二重で回す。
2つ目のforeachにだけ&
をつけてもうまくいかない。
test.php
$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←おかしい
1 =>
array (size=1)
'values' =>
array (size=2)
0 => int 3
1 => int 4
*/
両方に&
をつけるとうまくいく。
test4.php
$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←正しい
1 =>
array (size=1)
'values' =>
array (size=2)
0 => int 3
1 => int 4
*/