配列を別の変数に代入するとコピーされる(参照ではない)
PHPの配列はオブジェクトと違い、代入すると中身がまるごとコピーされます。コピー先の配列を変更しても、元の配列には影響しません。
なぜエラーが出ないのか
出力: 1,2,3 / 1,2,3
(エラーなし)- PHPは何も報告しません。文法として正しいためです
出力: 1,2,3 / 1,2,3- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 <?php 2 $a = [3, 1, 2]; 3 $b = &$a ; ^ 4 sort($b); 5 echo implode(",", $a) . " / " . implode(",", $b);
出力: 1,2,3 / 1,2,3期待: 3,1,2 / 1,2,3 (エラーにはなりません)
&$aで参照渡しにすると$bは$aと同じ配列を指すため、sort($b)が$aまで並べ替えてしまいます。単に$aと書けば値がコピーされ、元の配列は影響を受けません。
直し方: &$a を $a にします。
広告
広告スロット(未設定)
パターン2
1 <?php 2 function sortInPlace(&$arr ) { ^ 3 sort($arr); 4 return $arr; 5 } 6 $original = [5, 3, 4]; 7 $sorted = sortInPlace($original); 8 echo implode(",", $original) . " / " . implode(",", $sorted);
出力: 3,4,5 / 3,4,5期待: 5,3,4 / 3,4,5 (エラーにはなりません)
引数を&$arrという参照渡しにすると、関数内のsort()が呼び出し元の$originalまで並べ替えてしまいます。PHPの配列引数は既定で値渡しなので、&を付けなければ元の配列は安全です。
直し方: &$arr を $arr にします。
パターン3
1 <?php 2 $cart = ["apple", "banana"]; 3 $backup = &$cart ; ^ 4 $backup[] = "cherry"; 5 echo count($cart) . " / " . count($backup);
出力: 3 / 3期待: 2 / 3 (エラーにはなりません)
&$cartとして参照渡しにすると$backupと$cartが同じ配列を共有し、$backupへの追加が$cartにも反映されてしまいます。
直し方: &$cart を $cart にします。
よくある誤解
JavaScriptやJavaの配列の感覚で「代入は参照を共有するはず」と思い込むと、PHPでは逆の結果になります。同じ配列を共有したい場合は明示的に参照渡し(&)を使う必要があります。
まとめ
配列を別の変数に代入するとコピーされる(参照ではない)は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。