php7のスロー可能な例外とエラー

過去には、致命的なエラーを処理することはほとんど不可能でした。 set_error_handler



によって設定されたハンドラーは呼び出されず、スクリプトは単純に完了します。

PHP 7では、致命的エラー(E_ERROR)および処理機能を備えた致命的エラー(E_RECOVERABLE_ERROR)が発生すると、例外がスローされ、スクリプトは終了しません。 ただし、「メモリ不足」などの特定のエラーは、引き続き停止します。 PHP 7でキャッチされないエラーは、PHP 5と同様に「致命的」になります。

php 7では、warinngやnoticeなどの他の種類のエラーは変更されないことに注意してください。


E_ERRORおよびE_RECOVERABLE_ERRORからスローされた例外は、 Exceptionから継承されません。 この分離は、5で記述されたコードによるこれらのエラーの処理を防ぐために行われました。 致命的なエラーの例外は、新しいクラスErrorのインスタンスになりました。 他の例外と同様に、 エラーはキャッチされ、処理され、 最終的にブロック実行されます。

投げられる


ErrorとExceptionの両方のクラスは、新しいThrowableインターフェイスを実装します。

新しい例外階層は次のとおりです。

 interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error
      
      







PHP 7コードでThrowableを定義すると、次のようになります。

 interface Throwable { public function getMessage(): string; public function getCode(): int; public function getFile(): string; public function getLine(): int; public function getTrace(): array; public function getTraceAsString(): string; public function getPrevious(): Throwable; public function __toString(): string; }
      
      





このインターフェイスは使い慣れている必要があります。 スロー可能なメソッドExceptionメソッドとほぼ同じです。 唯一の違いは、 Throwable :: getPrevious()Exceptionだけでなく、任意のThrowableインスタンスを返すことができることです。 ExceptionおよびErrorコンストラクターは、 Throwableインスタンスを前の例外として受け入れます。

Throwabletry / catchブロックで使用して、 ExceptionError (および将来発生する可能性のある他の例外)の両方をキャッチできます。 特定のクラスの例外で例外をキャッチし、各タイプを個別に処理することをお勧めします。 ただし、例外をキャッチする必要がある場合があります。 PHP 7では、すべての例外のtry / catchブロックはExceptionではなくThrowableを使用する必要があります

 try { // Code that may throw an Exception or Error. } catch (Throwable $t) { // Handle exception }
      
      







カスタムクラスはThrowableを実装できません。 これは予測可能性のために行われました。 例外またはエラーインスタンスのみがスローされます。 さらに、例外にはスタックトレースでオブジェクトが作成された場所に関する情報が含まれます 。 カスタムクラスには、この情報を保存するために必要なパラメーターがありません。



エラー


PHP 5.xおよびPHP 7のほとんどすべてのエラー(E_ERROR、E_RECOVERABLE_ERROR)は、 Errorのインスタンスによってスローされます。 他の例外と同様に、 エラーはtry / catchブロックを使用してキャッチできます。

 try { $undefined->method(); // Throws an Error object in PHP 7. } catch (Error $e) { // Handle error }
      
      







PHP 7のPHP 5.xで「致命的」だったエラーのほとんどは、単純なErrorオブジェクトをスローしますが、サブクラスオブジェクトTypeErrorParseErrorおよびAssertionErrorをスローするものもあります。



TypeError


メソッドの引数または戻り値が宣言された型と一致しない場合、 TypeErrorインスタンススローされます。



 function add(int $left, int $right) { return $left + $right; } try { $value = add('left', 'right'); } catch (TypeError $e) { echo $e->getMessage(), "\n"; } //Result: //Argument 1 passed to add() must be of the type integer, string given
      
      







ParseError


evalinclude(require / require )ファイルまたはコードに構文エラーが含まれている場合、 ParseErrorがスローされます。

 try { require 'file-with-parse-error.php'; } catch (ParseError $e) { echo $e->getMessage(), "\n"; }
      
      







AssertionError


assert()メソッドで指定された条件が満たされない場合、 AssertionErrorがスローされます。

 ini_set('zend.assertions', 1); ini_set('assert.exception', 1); $test = 1; assert($test === 0);
      
      





 Fatal error: Uncaught AssertionError: assert($test === 0)
      
      





assert()メソッドが実行され、設定で有効になっている場合にのみAssertionErrorがスローされます: zend.assertions = 1およびassert.exception = 1



コードでエラーを使用する


Errorクラスを使用し、 Errorクラスの独自の階層を作成してErrorを拡張することもできます。 これは、どの例外が例外をスローすべきか、どのエラーかという疑問を投げかけます

エラーは、プログラマーの注意を必要とするコード内の問題(間違ったタイプの入力エラーや構文エラーなど)を示すために使用する必要があります。 例外を「安全に」処理でき、プログラムの実行を続行できる場合は、例外を使用する必要があります。

Errorオブジェクトはプログラム実行中に処理できないため、 Errorをキャッチすることはまれです。 一般に、 エラーは、ログの記録、必要な「データのクレンジング」、およびユーザーへのエラー表示のためにのみ捕捉する必要があります。



PHP 5.xとPHP 7の両方で例外をキャッチする


1つのコードを使用してphp 5.xとphp 7の両方で例外をキャッチするには、まずThrowableをキャッチし、次にExceptionをキャッチする複数のcatchブロックを使用します 。 PHP 5.xのサポートが不要になったら、 Exception catchブロックを削除するだけです。

 try { // Code that may throw an Exception or Error. } catch (Throwable $t) { // Executed only in PHP 7, will not match in PHP 5.x } catch (Exception $e) { // Executed only in PHP 5.x, will not be reached in PHP 7 }
      
      






All Articles