variables_orderの設定とgetenv()推進キャンペーン
こんにちは、亀本です。
先日、私用がてらにふらりと遊びに来てくださっていたid:rskyさんと共に、アシアルの何名かでウノウさんへちょびっと遊びに行ってきました。
そこで自分は使えなキャラだったことが判明し、軽くションボリ中です(´・ω・`)
さて、今回はスーパーグローバル変数周りのお話です。
知ってる人は知っている事だと思うので恐縮ですが、ちょっとした小ネタです。
普段わりと忘れられがちなのですが、スーパーグローバル変数の値はどんな時でも必ず取得できるわけではありません。
スーパーグローバル変数の値のうち、$_GET、$_POST、$_COOKIE、$_SERVE、$_ENVの5つは、php.iniの中のvariables_orderというディレクティブによって、値のパースを行うかどうかが規定されています。
ソースからコンパイルした場合、php.ini-distであれば
各ディストリビューションでも多くの場合はphp.ini-distと同じです。(ただ、ここは未確認の部分も多いです。)
E、G、P、C、SはそれぞれENV、GET、POST、COOKIE、SERVERの指定で、これらがそれぞれ指定されているかどうかで、各変数がパースされるかどうかが決まります。
つまり、上記の例でいえばphp.ini-recommendをシステムで使用した場合、$_ENVの中身は空っぽ、ということになります。
G、P、C、SはWebアプリケーションではほぼ必須なのでOFFになっていることは少ないですが、$_ENVはあまり使う機会が多くないので、Eの指定がOFFになっていることが忘れられがちですし、ONにする要件もあまりありません。
むしろ、phpinfo()の情報が誤って漏洩した時のリスクを高めるだけなので、あえて変更することは考えにくいでしょう。
余談ですが、この指定をすべて消して
全PHPバージョンで確認したわけではありませんが、実際には空文字列にしてしまうと全てのスーパーグローバル変数が設定されます。つまり"EGPCS"と指定したのと同じことになります。
まぁ、このような指定は通常考えられないので、問題はないのですが。。。
さて、本題に戻ります。
最近はPHPの設定ベースとしてphp.ini-recommendが推奨されていることも多く、上記のような設定になっている状況は間々あります。
そのため、気をつけておかないと、php.ini-distベースで運用していたテストサーバで組んだCLIバッチがphp.ini-recommendベースで運用している本番上では$_ENVが設定されていないためにエラーになる、という罠にはまることもあります。
また、ライブラリで$_ENVを使っていると、php.ini-recommendベースのシステムでは毎回こういった問題に当たることになります。
この問題を起こさないようにする為に、ライブラリやバッチを作成する場合には$_ENVではなくgetenv()関数を用いるとよいでしょう。
PHPのgetenv()関数はC言語のgetenv()関数の単純なラッパーになっており、上記の設定に依存することなく指定した環境変数の値を取得します。
そのため、$_ENVに値が設定されていない場合でも、getenv()関数を用いれば(環境変数に値が存在する限り)取得が可能です。
ということで、現在getenv()推進キャンペーン展開中です(`・ω・´)
(※別にアシアルで推奨、って意味じゃないですよ。個人的な話です。)
なお、補足ですが、この件に関して/halt/snapshotにて
特にライブラリで使用する場合には、取得してくる値がグローバルであることの明示という意味合いからも、このような処理の方が望ましいかもしれませんね。
先日、私用がてらにふらりと遊びに来てくださっていたid:rskyさんと共に、アシアルの何名かでウノウさんへちょびっと遊びに行ってきました。
そこで自分は使えなキャラだったことが判明し、軽くションボリ中です(´・ω・`)
さて、今回はスーパーグローバル変数周りのお話です。
知ってる人は知っている事だと思うので恐縮ですが、ちょっとした小ネタです。
普段わりと忘れられがちなのですが、スーパーグローバル変数の値はどんな時でも必ず取得できるわけではありません。
スーパーグローバル変数の値のうち、$_GET、$_POST、$_COOKIE、$_SERVE、$_ENVの5つは、php.iniの中のvariables_orderというディレクティブによって、値のパースを行うかどうかが規定されています。
ソースからコンパイルした場合、php.ini-distであれば
- variables_order
= "EGPCS"
- variables_order
= "GPCS"
各ディストリビューションでも多くの場合はphp.ini-distと同じです。(ただ、ここは未確認の部分も多いです。)
E、G、P、C、SはそれぞれENV、GET、POST、COOKIE、SERVERの指定で、これらがそれぞれ指定されているかどうかで、各変数がパースされるかどうかが決まります。
つまり、上記の例でいえばphp.ini-recommendをシステムで使用した場合、$_ENVの中身は空っぽ、ということになります。
G、P、C、SはWebアプリケーションではほぼ必須なのでOFFになっていることは少ないですが、$_ENVはあまり使う機会が多くないので、Eの指定がOFFになっていることが忘れられがちですし、ONにする要件もあまりありません。
むしろ、phpinfo()の情報が誤って漏洩した時のリスクを高めるだけなので、あえて変更することは考えにくいでしょう。
余談ですが、この指定をすべて消して
- variables_order
= ""
全PHPバージョンで確認したわけではありませんが、実際には空文字列にしてしまうと全てのスーパーグローバル変数が設定されます。つまり"EGPCS"と指定したのと同じことになります。
まぁ、このような指定は通常考えられないので、問題はないのですが。。。
さて、本題に戻ります。
最近はPHPの設定ベースとしてphp.ini-recommendが推奨されていることも多く、上記のような設定になっている状況は間々あります。
そのため、気をつけておかないと、php.ini-distベースで運用していたテストサーバで組んだCLIバッチがphp.ini-recommendベースで運用している本番上では$_ENVが設定されていないためにエラーになる、という罠にはまることもあります。
また、ライブラリで$_ENVを使っていると、php.ini-recommendベースのシステムでは毎回こういった問題に当たることになります。
この問題を起こさないようにする為に、ライブラリやバッチを作成する場合には$_ENVではなくgetenv()関数を用いるとよいでしょう。
PHPのgetenv()関数はC言語のgetenv()関数の単純なラッパーになっており、上記の設定に依存することなく指定した環境変数の値を取得します。
そのため、$_ENVに値が設定されていない場合でも、getenv()関数を用いれば(環境変数に値が存在する限り)取得が可能です。
ということで、現在getenv()推進キャンペーン展開中です(`・ω・´)
(※別にアシアルで推奨、って意味じゃないですよ。個人的な話です。)
なお、補足ですが、この件に関して/halt/snapshotにて
- if
($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { return $var; - }
特にライブラリで使用する場合には、取得してくる値がグローバルであることの明示という意味合いからも、このような処理の方が望ましいかもしれませんね。
トラックバックURI
最近の記事
システム開発エンジニア募集! [2012年02月03日 : 小林有佳]
OpenVPNで細々便利な設定 [2012年01月31日 : 門脇優児]
【iOS】Viewの開発・デバッグに役立つ色々 [2012年01月23日 : 中川善樹]
PHPDocumentorの利用方法まとめ [2012年01月19日 : 笹亀弘]
Google Chart Toolsを使ってサイトマップを描こう! [2011年12月21日 : 志田仁美]
stumpwm設定v2 [2011年12月19日 : 門脇優児]
Mashup Awards 7の授賞式が行われました [2011年12月16日 : 中川善樹]
社員旅行に行きました [2011年12月12日 : 大橋寛子]
iCloud風のアイコンを作成する(Fireworks) [2011年12月07日 : 和田記光]
iScroll4でネイティブに近いスマホ向けHTMLページを作成する [2011年12月02日 : 松田惇]













コメントフォーム