hnwの日記

PHPのシンボルテーブルを覗いてみる

PHPのシンボルテーブルというのはC実装のレベルの用語で、その時点で有効な変数テーブルのことを指します。つまり、グローバルスコープならグローバル変数を管理する変数テーブル、関数スコープならローカル変数を管理する変数テーブルの意味になります。


今回、自作エクステンションhnw/php-arraydumperでシンボルテーブルをvar_dump()するだけの関数symbol_table_dump()を実装してみました。下記のように使います。

<?php
function foo($a = 1) {
    $b = 2
    symbol_table_dump();
}
foo("bar");


出力は次のようになります。

array(2) {
 ["a"]=>
 string(3) "bar"
 ["b"]=>
 int(2)
}


このシンボルテーブルは$$varのようなイカれた変数アクセスの際に参照する必要がありますが、そうでも無い限り不要です。通常のローカル変数はコンパイル時に全部解決できてしまうので、通常の変数アクセスのみであれば実行時にシンボルテーブルへのアクセスは発生しないのです。


実際、PHP 5.3以降ではローカル変数に対応するシンボルテーブルは必要になるまで作られません。$$varのような変数アクセスがあったタイミングで内部的にzend_rebuild_symbol_table()が呼び出され、そのスコープに対応するシンボルテーブルが構築されます。


逆に言うと、$$varのような変数アクセスを多用するのは性能面でペナルティがあると言えるかもしれません。もちろん致命的な性能差が出るほどではないでしょうし、そもそもそんな変数アクセスをしたい状況が珍しいとは思いますが。