WebEngine

だらだらと綴る技術系メモ

PHPのforeachの罠

foreachの$valueは参照渡しではない

$arrayに格納されている要素を、すべて空文字列に置き換えたいとします。
方法はいろいろありますが、今回はforeachの話なので、foreachを使います。

<?php

$array = array("php", "python", "ruby", "javascript");

foreach ($array as $value) {
  $value = "";
}

var_dump($array);

実行結果は次のようになります。

array(4) {
  [0]=>
  string(3) "php"
  [1]=>
  string(6) "python"
  [2]=>
  string(4) "ruby"
  [3]=>
  string(10) "javascript"
}

要素はそのままになっていますね。これは、$valueを直接変更したからです。
PHPの場合、foreachで取り出した要素は、その要素をコピーする形になります。
$valueは、$arrayの要素と同じアドレスを見ていない、というわけです。

解決策1

上記では、値渡しになっているので、参照渡しにすれば良い、という考え方です。

<?php

$array = array("php", "python", "ruby", "javascript");

foreach ($array as &$value) {
  $value = "";
}
unset($value);

$valueの前に&をつけて参照渡しにしています。
こうすることで、すべての要素を空文字列にすることができました。
注意点として、処理後、unset($value)で参照渡しをクリアしてやることが大事です。
処理したあとも、参照渡しである状態が保持されつづけると、思わぬバグの温床となります。

解決策2

参照渡しにするのではなく、$arrayの方を直接書き換える、という手法になります。

<?php

$array = array("php", "python", "ruby", "javascript");

foreach ($array as $key => $value) {
  $array[$key] = "";
}

キーを取得して、そのキーで要素を指定することによって配列を操作しています。
僕はこちらの方をよく使っています。