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の記述上、変数をコピーしたからといって、メモリ上で値がコピーされているわけではないんですね。(勘違いしてました・・・)
メモリ上で値がコピーされるのは、
「コピーした変数に対して代入が行われた場合」
となる。


値の参照だけなら、コピー渡ししてもそれほど性能劣化しないということですね。勘違いしやすいので気をつけておこうっと。