php.ini-recommendedで、variables_orderがGPCSである理由と、PHP5のauto_globals_jit
遅ればせながら関連ネタ。
ライブラリの類で$_ENVを使うのはやめてgetenv()を使いましょうって思った。
getenv()推進キャンペーンを考えた - 絶品ゆどうふのタレ
これには同感。recommendedが variables_order="GPCS" である以上、多くの環境*1で手を加えずに動かせるようにするためには、それがいいか悪いかは関係なく、これを基準として動くアプリケーションを書いた方がいいと思います。
なぜ、variables_orderに "E" が含まれないのか
recommended = オススメ設定なのだけれど、どういう理由なのか。これは、php.ini-recommendedのコメントにあるように、パフォーマンス対策とのこと。
; - variables_order = "GPCS" [Performance]
http://cvs.php.net/viewvc.cgi/php-src/php.ini-recommended?revision=1.179.2.11.2.23&view=markup
; The environment variables are not hashed into the $_ENV. To access
; environment variables, you can use getenv() instead.
これは簡単な話で、作るのにコストがかかるから。環境変数を取ってきて、スーパーグローバル変数の配列に詰めないといけない。使わないのだったら無駄になってしまいます。
ただ、逆に環境変数を多用して、getenv()を大量にコールすることになると、作られた配列の参照よりも、逆に時間がかかってしまうので、こちらがパフォーマンスの面でよいとは一概には言えない。だけれど、普通のウェブアプリでそういうことはしないよねー、ということで E が含まれてないのではと思います。
これは突き詰めると、EGPCSの残りのものにも同じことが言えます。Webサーバ上で動かすことが基本となるので、さすがに GPCあたりを外してしまうのはアレだけれども、$_SERVER
は、使わないことが無いこともないので、前にも書いたOmniTIのGeorge Schlossnagle氏のZend Conferenceで発表したスライド(PDF)の29ページにあるように、
variables_order = "GPC"
と、S
すら外してしまうのもアリです。そして、この値もgetenv()
から取得することができます。(PHPのgetenv()は、最初にSAPI側の用意するsapi_getenv()を叩いて、該当しなければ普通のgetenv()をコールしています。Apacheだと、sapi_getenv()で取れる値は、$_SERVERと同じ。他は知らない)
コストがかかるというのはPHP4までの話
上のように使わないものを作るのはイケてないねー、ということで、PHP5からは、参照されたときに始めてスーパーグローバル変数が作成されるJIT (Just in Time)の仕組みが採用されています。すなわち使われなければ生成されることもありませんので、使わなくて無駄ということがなくなります。デフォルトで有効です。
PHP4と仕組みが異なることから、無効にすることもでき、その設定項目が [http://php.net/ini.core#ini.auto-globals-jit:title=auto_globals_jit]
。Onであれば有効に、Offなら無効になり、Offの場合はJITではなく、従来と同じようにリクエスト初期化フェーズでvariables_orderに指定された各グローバル変数が生成されます。
普通にPHPスクリプトで扱っている場合は、何も動作の変化は感じられないのですが、お行儀の悪いExtensionなんかがいるとうまく値を取れなくなることがあります。過去、APCがそういう状態だったようです。(PHP :: Bug #56445 :: APC - superglobals empty once script is cached)
名前 | デフォルト | 変更の可否 |
---|---|---|
auto_globals_jit |
"1" |
PHP_INI_PERDIR |
で、これは php.ini-recommended でもOn
です。
; When enabled, the SERVER and ENV variables are created when they're first
http://cvs.php.net/viewvc.cgi/php-src/php.ini-recommended?revision=1.179.2.11.2.23&view=markup
; used (Just In Time) instead of when the script starts. If these variables
; are not used within a script, having this directive on will result in a
; performance gain. The PHP directives register_globals, register_long_arrays,
; and register_argc_argv must be disabled for this directive to have any affect.
auto_globals_jit = On
結論
PHP5においては、recommendedの設定だと、auto_globals_jit
が有効なので、$_ENV
が含まれていることによるパフォーマンスへの影響はないんでないかと思います。
けど、そういう環境がある以上、$_ENV
の利用は避けるといいです。
詳しい実装については気が向いたらまとめる。
*1:個人的には、ずっと$_ENVも$_SERVERも無い環境に触れてきたので、使わないのが染みついてます