2011年9月18日日曜日

phpのエラーハンドリング

エラーを適切にキャッチし、記録し、対策することはどんな言語を使っていても重要です。 phpでこれらの処理を行うのによく使う関数やディレクティブを並べてみました。


関数

error_reporting
出力する PHP エラーの種類を設定する

ディレクティブ

error_reporting
error_reporting()関数同様の機能。ただし演算子の記述に制限あり
display_errors
エラーをHTML出力の一部として画面に出力するかどうかを定義する
log_errors
エラーメッセージを、サーバーのエラーログまたはerror_logに記録するかどうかを指定する
error_log
スクリプトエラーが記録されるファイル名を指定する

それぞれのおすすめ設定

error_reporting

E_NOTICEもログ出力しておくとバグに気づくことがあります。

display_errors

開発環境ではtrue、本番環境ではfalse(これは必須)

log_errors

開発環境、本番環境問わずtrue

error_log

省略するとapacheのエラーログに記録されます。アプリケーション個別のエラーログファイル名を決めて指定することを推奨。

まとめ

  • 本番環境、開発環境問わずerror_reportingにはE_NOTICEも記録する
  • 本番環境ではdisplay_errorsは必ずfalseを指定。開発環境ではお好みですが、trueを設定しておくと画面に表示されるので対応漏れを減らすことができます。
  • エラーログはアプリケーションごとにファイルを分ける。これにより、監視するときもアプリケーション単位で行うことができます。

注意

error_reportingに設定するE_ALLの値がphpのバージョンで変わります。 このせいでphpのバージョンアップをしたとたんに大量のエラーログに見舞われることがあります。これについてはまた別の機会に。

2011年9月2日金曜日

phpでメモリ使用量に気を使う意味

phpはそのスクリプトで使用するメモリの上限を memory_limit というphp.iniのディレクティブで設定できますが、このデフォルト値はphpのバージョンによって変わります。
PHP 5.2.0より後では"128M"、PHP 5.2.0 より前は "8M"、PHP 5.2.0 では "16M"
となっており、php 5.2.0より前ではかなり少ない値となっています。 このメモリ制限のしくみは、便利でもあり、不便に思うこともあります。

リクエストを処理してレスポンスを返すウェブアプリケーションではメモリを大量に使用することはまれです。memory_limitののおかげでバグを仕込んでしまったループでメモリが消費されてエラーで気づいて助かったことがあります。

いっぽう、バッチ処理のようなスクリプトでは、内容にもよりますがメモリ使用量に気をつけていないと、途中で「PHP Fatal error: Allowed memory size of **** bytes exhausted」が発生して、中断してしまい悲惨です。

これを避けるために、memory_get_usage()でメモリ使用量を調査するデバッグコードを仕込んでおくのは良い習慣といえるでしょう。そして、もしPHP Fatal Error:...が発生してしまったら、まずロジックに問題がないか調べ、それからmemory_limitの値の変更を検討します。

そして、明示的にmemory_limitを指定しておけばphpのバージョンアップによる影響も避けられます(ini_setで設定できるのでスクリプトごとに変えられます)