LoginSignup
0
0

More than 1 year has passed since last update.

PHPでループの要素を参照渡しにするときの注意

Last updated at Posted at 2022-06-28

PHPのループで参照渡しを使ったコードが思い通りの挙動にならず、いろいろ調べてたら面白い例を見つけたので紹介。

こんなコードがあったとする。

$a = array('a', 'b', 'c', 'd');

foreach ($a as &$v) {}

print_r($a);

foreach ($a as $v) {}

print_r($a);

2回のprint_r($a);の結果は同じになりそうなものだけど実際は以下のようになる。

Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
)
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => c
)

なぜかというと、まず1個目のループは参照渡しなので、

$vがaが入ってる1個目のコンテナ(※)を指す
$vがbが入ってる2個目コンテナを指す
$vがcが入ってる3個目コンテナを指す
$vがdが入ってる4個目コンテナを指す

という流れで$vのポインターが4個目のコンテナに移動する。

※コンテナ = 値の格納場所。「zval」とも呼ばれる

2個目のループの間$vは4個目のコンテナに対するポインターとして機能しているので、

$v=aで4個目のコンテナの中身がaになる
$v=bで4個目のコンテナの中身がbになる 
$v=cで4個目のコンテナの中身がcになる 

という現象が起き、上記の時点で配列の中身がabccになってしまう。

対策としては、一個目の配列の後にunset($v)$v→4個目のコンテナの参照を切ると解消される。

$a = array('a', 'b', 'c', 'd');

foreach ($a as &$v) {}

print_r($a);

unset($v);

foreach ($a as $v) {}

print_r($a);
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
)
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
)

参考

0
0
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
0