こんにちは。よっしーです(^^)
今日は、PHPのErrorsについてご紹介します。
背景
PHP8.2を利用したAPIを開発しているときにErrorsを利用したので、そのときの調査内容を備忘としてのこしました。
こちらのサイトを参考にしています。
例外
PHPは他のプログラミング言語と似た例外モデルを持っています。例外はスローされ、PHP内でキャッチされることがあります。コードは潜在的な例外のキャッチを容易にするために try ブロックで囲むことができます。各 try ブロックには少なくとも1つの対応する catch または finally ブロックが必要です。
例外がスローされ、その現在の関数スコープにキャッチブロックがない場合、例外は呼び出しスタックを上方に “バブルアップ” して呼び出し元の関数に一致する catch ブロックを見つけるまで移動します。途中で出会うすべての finally ブロックが実行されます。一致する catch ブロックが見つからず、呼び出しスタックがグローバルスコープにまでアンワインドされると、グローバル例外ハンドラが設定されていない限り、プログラムは致命的なエラーで終了します。
スローされるオブジェクトは Throwable のインスタンスである必要があります。Throwable でないオブジェクトをスローしようとすると、PHP致命的なエラーが発生します。
PHP 8.0.0以降、throw キーワードは式であり、任意の式コンテキストで使用できます。以前のバージョンでは文であり、独自の行である必要がありました。
catch
catch ブロックはスローされた例外に対する応答方法を定義します。catch ブロックは、ハンドルできる例外またはエラーの1つ以上のタイプを定義し、オプションで例外を割り当てる変数を指定します(PHP 8.0.0以前は変数が必須でした)。スローされたオブジェクトの型と一致する最初の catch ブロックがオブジェクトを処理します。
複数の catch ブロックを使用して、異なる種類の例外をキャッチできます。通常の実行(try ブロック内で例外がスローされない場合)は、シーケンスで定義された最後の catch ブロックの後に続行されます。例外は catch ブロック内でスロー(または再スロー)できます。そうでない場合、トリガーされた catch ブロックの後に実行が続行されます。
例外がスローされると、ステートメントの後に続くコードは実行されず、PHPは最初に一致する catch ブロックを見つけようと試みます。例外がキャッチされない場合、set_exception_handler() でハンドラが定義されていない限り、「Uncaught Exception …」というメッセージが付いた PHP致命的なエラーが発行されます。
PHP 7.1.0以降、catch ブロックはパイプ(|)文字を使用して複数の例外を指定できます。これは、異なるクラス階層からの異なる例外が同じように処理される場合に便利です。
PHP 8.0.0以降、捕捉した例外の変数名はオプションです。指定されていない場合、catch ブロックは実行されますが、スローされたオブジェクトにアクセスできません。
finally
finally ブロックは catch ブロックの代わりまたは後に指定することもできます。finally ブロック内のコードは、例外がスローされたかどうかにかかわらず、try および catch ブロックの後に常に実行され、通常の実行が再開されます。
注目すべき相互作用の1つは、finally ブロックと return ステートメントの間にあります。try ブロックまたは catch ブロック内で return ステートメントがエンカウンターされた場合、finally ブロックは依然として実行されます。さらに、return ステートメントはエンカウンターされたときに評価されますが、その結果は finally ブロックの実行後に返されます。さらに、finally ブロックにも return
ステートメントが含まれている場合、finally ブロックの値が返されます。
グローバル例外ハンドラ
例外がグローバルスコープにバブルアップする場合、それが設定されていればグローバル例外ハンドラによってキャッチされることがあります。set_exception_handler() 関数は、他のブロックが呼び出されない場合にキャッチブロックの代わりに呼び出される関数を設定できます。その効果は、その関数が catch として設定された try-catch ブロックでプログラム全体がラップされているかのようです。
注意事項
内部のPHP関数は主にエラーレポートを使用し、現代のオブジェクト指向の拡張機能のみが例外を使用します。ただし、非致命的なエラーに対しては、ErrorExceptionを使用してエラーを例外に簡単に変換できます。
例 #1 エラーレポートを例外に変換する
function exceptions_error_handler($severity, $message, $filename, $lineno) {
throw new ErrorException($message, 0, $severity, $filename, $lineno);
}
set_error_handler('exceptions_error_handler');
標準PHPライブラリ(SPL)には多くの組み込みの例外が用意されています。
おわりに
今日は、PHPのErrorsについてご紹介しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント