PHPでエラー抑制演算子@を正当に使ってるなぁと思ったケース
私も以前はエラー抑制演算子@は悪だと思っていた時期がありました。
PHP プログラマが "@" を使うべきでない 5 つの理由 - 肉とビールとパンケーキ by @sotarok
によると、以下の理由で@は使うべきではないそうです。
- エラーが発生する理由がわからない
- @をつけるクセがつくと適切に値のチェックをする方法が身に付かない
- エラーのハンドリングによっては意味をなさない
- 遅い
- きもちわるいから
私もおおむね同意です。ただ、「エラーのハンドリングによっては意味をなさない」はエラーのハンドリング自体を語る上で@だけをことさらにあげつらうのは本質的ではないし、「きもちわるい」はべつに@に限ったことではないのでどうかと思います。
で、あるXOOPSのモジュールのコードを読んで行くなかで、それでも「少しでもコードを早く書く」という目的において下記のケースで@を使っているケースがありました。
それは、あるファイルに変数が書いてあって、それをincludeしたい場合です。*1
たとえば、正確にやるなら
<?php if (file_exists('./vars.inc.php')){ include './vars.inc.php'; if (isset($pref_array)){ /// 何かする } }
ってやるところを、そのコードでは
<?php if (@include './vars.inc.php'){ if (isset($pref_array)){ /// 何かする } }
ってやってました。これは、先述のどれもをクリアしたうえで@を使っています。vars.inc.phpに適当な配列を書いて一万回ループしてみまして時間を計ってみましたが、
if分岐
real 0m0.669s
user 0m0.551s
sys 0m0.117s
@
real 0m0.655s
user 0m0.523s
sys 0m0.132s
となり、若干速いくらいです。
このコードを書いたのは実行速度を気にされている方でPHPのベテランで個人的にも良く知っている方なので、@を使ってるよ!とちょっとびっくりしつつ、しかしこの方法であればなるほどなぁと納得した次第でした。
ひと粒で2度
実はこのコードで最初気になったのは、
<?php if (@include './vars.inc.php'){
の部分でした。includeって、正当に読み込んだかどうかの結果を返してるんですよね。
これ知らなかったです。
結論:思考がわかってる人のコードをよく読むと勉強になる。
追記 20090723
トラックバックで
includeの返り値について - _ - sideport
includeされたファイルの中からreturnで返されると、ファイルが読み込まれたかどうかではなく、returnに使われた値がincludeの返り値として使われる。
そのとおりです。間違えてました。
ひそかに敬愛するp0tさんにも書かれてた。
てか、自分も昔同じようなエントリ書いてた。半年前。
いまさら知らなかったPHPのincludeの返り値 - ・・・tohokuaikiのチラシの裏(それ図解できたらいいなぁ)
どーなん、この鳥頭。
*1:なので、これは、include_onceは不可なケースです