trigger_errorでE_USER_*の警告を発行する
trigger_errorは、処理は止めないが伝えたい問題をPHPのエラー機構に乗せて通知する関数です。E_USER_NOTICE/WARNING/DEPRECATEDでレベルを使い分けられます。
例外ではなく警告を出したい場面
処理は止めたくないけれど「これは良くない使い方ですよ」と知らせたい、というときがあります。例外を投げると処理が中断してしまうので、そこまでではない。そういう場面で trigger_error() を使うと、PHP のエラー機構に乗せて警告を発行できます。ログにも通常のエラーと同じ経路で流れるのが利点ですね。
function calc(int $a, int $b): int
{
if ($b === 0) {
// 致命的ではないが知らせたい
trigger_error('0 除算を回避し 0 を返します', E_USER_WARNING);
return 0;
}
return intdiv($a, $b);
}
例外にするか警告にするかは「呼び出し側に処理を続けさせてよいか」で判断すると分かりやすいと思います。
E_USER_* のレベルを使い分ける
第2引数でレベルを選べます。E_USER_NOTICE(軽い通知)、E_USER_WARNING(警告)、E_USER_ERROR(致命的)、そして非推奨を伝える E_USER_DEPRECATED があります。E_USER_ERROR はスクリプトを止めるので使いどころは限られますが、廃止予定の関数を知らせる DEPRECATED はライブラリ作者にとって便利ですね。
function oldApi(): void
{
trigger_error(
'oldApi() は非推奨です。newApi() を使ってください',
E_USER_DEPRECATED
);
// 旧実装は残しつつ移行を促す
}
デフォルトは E_USER_NOTICE です。移行を促したいだけなら DEPRECATED、実行時の異常を知らせたいなら WARNING、という感覚で選んでいます。
ハンドラで一元的に受ける
set_error_handler() を仕込んでおくと、trigger_error() で出したものも含めてエラーを一箇所で捕まえられます。ログ整形したり、開発中は例外に変換して早めに気づけるようにしたり、といった運用ができますね。ただし E_USER_* 以外の一部エラーはハンドラで捕捉できない点だけ頭に入れておくとよいです。
set_error_handler(function (int $level, string $msg, string $file, int $line) {
error_log("[{$level}] {$msg} @ {$file}:{$line}");
return true; // 標準ハンドラを抑制
});
trigger_error('設定が未指定です', E_USER_NOTICE);
まとめ
trigger_error() は、処理を止めるほどではないが伝えたい、という場面で PHP のエラー機構に乗せて通知する手段です。レベルを E_USER_NOTICE / WARNING / DEPRECATED で使い分け、廃止予定の告知には DEPRECATED が向いています。set_error_handler() と組み合わせれば出力先やフォーマットを一元管理できるので、ログ運用まで含めて整えておくと扱いやすいと思います。
よくある質問
Q. 例外とtrigger_errorはどう使い分けますか。
A. 呼び出し側に処理を続けさせてよいかで判断します。止めたくないが伝えたいときは警告、中断すべきときは例外です。
Q. 廃止予定の関数を知らせたいときは。
A. E_USER_DEPRECATED を使うと、旧実装を残したまま移行を促せます。
Q. trigger_errorの出力をまとめて扱えますか。
A. set_error_handler() を仕込むと、trigger_errorで出したものも含めて一箇所で捕まえられます。