PHPの変数の管理について
基本的なことなのかもしれないけど。
PHPの変数は内部的には
- 変数コンテナー(zvalコンテナー)
- シンボルテーブル
というもので管理されているそうです。
「変数コンテナー」は変数の実体を管理する箱で、
- 変数の値
- 変数の型
- 変数が参照かどうか
- 参照カウンタ
というようなものを持っています。
「シンボルテーブル」は変数名と変数の実体(変数コンテナー)の
マッピングを管理します。
連想配列のように[変数名] => [変数コンテナーへのポインタ]
また、グローバルなテーブルとローカルなテーブルがあり、関数の内外で異なるテーブルを使用して別管理とすることでスコープを表現しているようです。
で、本題。
$a = 100;
のように変数を定義すると、「変数コンテナー」(C-a)が生成され、「シンボルテーブル」には、"a" => C-a という情報ができます。
ここで
$b = $a;
とすると、新たに「変数コンテナー」(C-b)が生成されるのではなく、(C-a)内の参照カウンタが1つ増えて2になるだけです。(実体は増えるわけではない)
「シンボルテーブル」には、
"a" => C-a
"b" => C-a
という情報ができます。
で
$b = 500;
この時に初めて、新たに「変数コンテナー」(C-b)が生成され(C-a)内の参照カウンタは1つ減り1になる。(実体が増える)
「シンボルテーブル」には、
"a" => C-a
"b" => C-b
という情報ができます。
つまりPHPの記述上、変数をコピーしたからといって、メモリ上で値がコピーされているわけではないんですね。(勘違いしてました・・・)
メモリ上で値がコピーされるのは、
「コピーした変数に対して代入が行われた場合」
となる。
値の参照だけなら、コピー渡ししてもそれほど性能劣化しないということですね。勘違いしやすいので気をつけておこうっと。