0
1

More than 3 years have passed since last update.

二次元配列をforeachで参照渡ししたい

Last updated at Posted at 2020-08-25

やりたいこと

以下のような二次元配列の一部を更新したい。

$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
*/
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1