PHPの配列の参照とデフォルト値とE_NOTICE
「@」でエラー抑制すると PHP が遅くなるという噂について
0.000000092秒が0.00000092秒になったところで心底どうでもいい。バッチ処理はPHPに向いてない と思うし、最適化するにしてもそんなミクロなとこより直すべき点が他にある。Webならファイルをgzipする、キャッシュを正しく使う、APC入れる、Apacheの不要モジュールを外すなどなど。
@を全部issetに直したら許容できるパフォーマンスが出た! なんてことは未来永劫ありえない。100万回もやれば結構な差がつくだろうと思ってたのに思いのほか微差だったので900万回ループ追加したらようやく1秒単位の違いになった、ていうシチュエーションがすべてを物語ってる。
速度はどうでもいい。問題はE_NOTICEの理想と現実をどう妥協していくかだと思う。
そもそもerror_reportingのデフォルト値を変えてE_NOTICEを加えてる時点で@なんか使わない宣言をしているに等しいと思うので、if(@$a["foo"])とか書くのはやっぱりおかしい。register_globalsをオフにしておいてextract($_REQUEST)
するような矛盾を感じる。
そうはいってもif(isset($_GET["foo"]) && $_GET["foo"] === "bar")なんてアホらしくていちいち書いてられないってのもわかる(最初のissetがないとE_NOTICE発生)。それに毎度毎度issetを書くなんていったらPerlとかRubyとかPythonとかJavaScriptとかLuaとかLispとかSmalltalkとか(中略)あたりの人に勤勉とかいって笑われる。
現状これに対するメジャーな妥協案は、
function _g($ary,$key,$default=null){
return isset($ary[$key]) ? $ary[$key] : $default;
}
if(_g($_GET,"foo","") === "bar"){
// do something
}
$display=_g($options,"display","none");
みたいなことをしてデフォルト値処理を自前で実装するやり方だろうか。なんかなあ。
と思ってちょっとググってみたところ、array_mergeでデフォルト値決める のがスマートだなあと感心しました。ただ、深い配列の場合は期待と違うくっつきかたになるのでやっぱり注意。
逆に考えるんだ。例えば、E_NOTICEを避ける。
開発時にE_NOTICEを有効にすることにはいくつ かの利点があります とか書いてるけど、E_NOTICEしててよかったことが1年以上のあいだで一度あったかどうか。逆にE_NOTICEエラーのせいでheader()が機能しないなど邪魔されたことは数知れず。
このへんのバランスは変数名typoのしやすさで個人差がありそうだけど、僕の場合は割に合わないのでとっととやめます。さようならE_NOTICE。ありがとうジョジョとIPA。こんにちは世界。