診断エラーは、従来からエラーと呼ばれてきたもので、
さまざまな状況を知らせるために使われます。
必要に応じて、画面に表示したりログに記録したりできます。
デフォルトでは、PHP はすべての診断エラーを報告します。
(PHP 8.0.0 より前のバージョンでは、E_NOTICE と
E_DEPRECATED の診断エラーはデフォルトでは報告されませんでした)
Throwable エラーとは異なり、ほとんどの診断エラーは
通常の処理の流れを中断しません。
E_ERROR のような致命的な診断エラーは、スクリプトを終了させます。
どの診断エラーを報告し、どれを無視するのかを決めるのが、
error_reporting
php.ini ディレクティブです。あるいは、実行時に
error_reporting() をコールして設定することもできます。
スクリプトの実行が始まる前に発生するエラーもあるため、
ディレクティブで設定しておくことを強く推奨します。
注意:
開発環境では常に、
error_reportingをE_ALLにしておくべきです。 PHP が発する報告にすべて気づいて対応できるようにするためです。 一方、運用環境では、もう少しレベルを下げてE_ALL & ~E_NOTICE & ~E_DEPRECATEDにすることもできますが、 多くの場合はE_ALLのままでも適切です。 潜在的な問題に早い段階で気づくことができるからです。
診断エラーが発生したときの PHP の挙動を決める php.ini ディレクティブが、あとふたつあります。
display_errors
は、診断エラーの内容をスクリプトの出力に含めるかどうかを設定します。
このディレクティブは、運用環境では常に無効にしておくべきです。
エラーメッセージの中には、データベースのパスワードなどの機密情報が含まれることもありえるからです。
しかし、開発環境では有効にしておくと便利なことがよくあります。
どこに問題があるのかに、すぐに気づけるからです。
log_errors
ディレクティブを有効にすると、PHP はエラーを表示するだけでなく、
診断エラーをログに記録することもできます。
発生したすべての診断エラーが、
error_log
で定義したファイルまたは syslog に書き出されます。
これは運用環境で非常に役立ちます。
診断エラーが発生した時点で記録され、
後からそのログをもとにレポートを生成できるからです。
@
演算子を使うと、個々の診断エラーを抑制できます。
PHP 8.0.0 より前のバージョンでは、PHP スクリプトの実行を終了させるような 重大な診断エラーでも抑制できました。
注意:
PHP のバージョンが変わると、診断エラーの追加や削除、深刻度の変更や Throwable エラーへの昇格が行われることがあります。
PHP のデフォルトの診断エラー処理では不十分な場合は、
set_error_handler() で独自のハンドラを設定して置き換えることができます。
E_ERROR や E_PARSE
などの一部の診断エラーは、この方法では処理できません
(完全な一覧は set_error_handler() を参照ください)。
それ以外の診断エラーは、さまざまな方法で処理できます。
たとえば、独自のハンドラで、ユーザーにはエラーページを表示しつつ、
メールの送信など、ログよりも直接的な方法でエラーを報告できます。
もうひとつの典型的な使い方は、 ErrorException を使って、診断エラーを例外に昇格させることです。
例1 診断エラーを例外に昇格させる
<?php
function exceptions_error_handler($severity, $message, $filename, $lineno) {
if (error_reporting() & $severity) {
throw new ErrorException($message, 0, $severity, $filename, $lineno);
}
}
set_error_handler('exceptions_error_handler');注意:
深刻度が現在の報告対象に含まれているかを 確認することが重要です。そうしないと、抑制された診断エラーに対しても 例外がスローされるため、
@演算子が機能しなくなります。
| バージョン | 説明 |
|---|---|
| 8.5.0 | (Maximum execution time exceeded のような) 致命的なエラーのメッセージに、 スタックトレースが含まれるようになりました。 |