Exception(例外)は、指定されたエラーが発生したときにスクリプトの通常の流れを変更するために使用されます。 例外とは何ですか? PHP 5 は、エラー処理に対する新しいオブジェクト指向アプローチを提供します。 例外処理は、指定されたエラー (例外) 状況が発生したときにスクリプトの通常のフローを変更するために使用されます。この状況を例外と呼びます。 例外がトリガーされると、通常は次のことが起こります。 現在のコード状態が保存されます。 コード実行が事前定義された例外ハンドラー関数に切り替わります。 状況に応じて、ハンドラーは、保存されたコード状態からコード実行を再開するか、スクリプト実行を終了するか、または次から開始します。コード内の別の場所でスクリプトの実行を続け、さまざまなエラー処理方法を示します: 例外の基本的な使用法 カスタム例外ハンドラーの作成 複数の例外 例外の再スロー 最上位の例外ハンドラーの設定
例外の基本的な使用法 例外がスローされると、後続のコードは実行を続行せず、PHP は一致する「キャッチ」コード ブロックを見つけようとします。 例外がキャッチされず、 set_Exception_handler() を使用して適切に処理されなかった場合、重大なエラー (致命的エラー) が発生し、「Uncaught Exception」エラー メッセージが出力されます。 例外をキャッチせずにスローしてみましょう:
リーリー上記のコードは次のようなエラーを受け取ります: 致命的なエラー: C:webfoldertest.php:6 のメッセージ「値は 1 以下である必要があります」を伴うキャッチされない例外 '例外' スタック トレース: #0 C:webfoldertest.php(12) ): checkNum(28) #1 {main} が C:webfoldertest.php の 6 行目でスローされました。 上記の例のエラーを回避するには、例外を処理する適切なコードを作成する必要があります。 ハンドラーの処理には以下を含める必要があります。 Try - 例外を使用する関数は「try」ブロック内にある必要があります。例外がトリガーされない場合、コードは通常どおり実行を続行します。ただし、例外がトリガーされると、例外がスローされます。 Throw - 例外をトリガーする方法を指定します。各「スロー」は少なくとも 1 つの「キャッチ」 Catch に対応する必要があります - 「キャッチ」コード ブロックは例外をキャッチし、例外情報を含むオブジェクトを作成します
例外をトリガーしてみましょう:
リーリー上記のコードは次のようなエラーを受け取ります: メッセージ: 値は 1 以下である必要があります 説明例: 上記のコードは例外をスローし、それをキャッチします:
checkNum()関数を作成します。数値が 1 より大きいかどうかを検出します。その場合は、例外をスローします。 「try」ブロックで checkNum() 関数を呼び出します。 checkNum() 関数で例外がスローされます。「catch」コード ブロックは例外を受け取り、例外情報を含むオブジェクト ($e) を作成します。 この例外オブジェクトから $e->getMessage() を呼び出して、この例外からのエラー メッセージを出力します
ただし、「各スローはキャッチに対応する必要がある」という原則に従うために、見逃したエラーを処理する最上位の例外ハンドラーをセットアップできます。 カスタム例外クラスの作成 カスタム例外ハンドラの作成は非常に簡単です。 PHP で例外が発生したときに関数が呼び出される特殊なクラスを作成しただけです。このクラスは例外クラスの拡張である必要があります。
このカスタム例外クラスは、PHP の例外クラスのすべてのプロパティを継承し、カスタム関数を追加できます。 例外クラスを作成することから始めましょう:
リーリーこの新しいクラスは、古い例外クラスのコピーに errorMessage() 関数を加えたものです。古いクラスのコピーであるため、古いクラスからプロパティとメソッドが継承され、getLine()、getFile()、getMessage() などの例外クラスのメソッドを使用できます。 説明例: 上記のコードは例外をスローし、カスタム例外クラスを通じてそれをキャッチします。customException() クラスは、古い例外クラスの拡張として作成されます。このようにして、古いクラスのすべてのプロパティとメソッドを継承します。 errorMessage() 関数を作成します。電子メール アドレスが不正な場合、関数はエラー メッセージを返します。$email 変数に不正な電子メール アドレス文字列を設定し、「try」コード ブロックを実行します。電子メール アドレスが不正であるため、例外が発生します。 「catch」コード ブロックが例外をキャッチし、エラー メッセージを表示します
複数の例外 スクリプトに複数の例外を使用して、複数の状況を検出できます。 複数の if..else ブロックまたは switch ブロックを使用したり、複数の例外をネストしたりできます。これらの例外は、異なる例外クラスを使用し、異なるエラー メッセージを返す可能性があります:
リーリー例の説明: 上記のコードは 2 つの条件をテストします。いずれかの条件が true でない場合は、例外がスローされます。
CustomException() クラスは、古い例外クラスの拡張として作成されました。このようにして、古いクラスのすべてのプロパティとメソッドを継承します。 errorMessage() 関数を作成します。電子メール アドレスが無効な場合、この関数はエラー メッセージを返します。 コードの「try」ブロックを実行すると、最初の条件では例外はスローされません。 電子メールには文字列「example」が含まれているため、2 番目の条件により例外がトリガーされます。 「catch」コード ブロックは例外をキャッチし、適切なエラー メッセージを表示しますcustomException がキャッチされず、基本例外がしっかりとキャッチされた場合、例外はそこで処理されます。
重新抛出异常 有时,当异常被抛出时,您也许希望以不同于标准的方式对它进行处理。可以在一个 "catch" 代码块中再次抛出异常。 脚本应该对用户隐藏系统错误。对程序员来说,系统错误也许很重要,但是用户对它们并不感兴趣。为了让用户更容易使用,您可以再次抛出带有对用户比较友好的消息的异常:
getMessage().' is not a valid E-Mail address.'; return $errorMsg; } } $email = "someone@example.com"; try { try { //check for "example" in mail address if(strpos($email, "example") !== FALSE) { //throw exception if email is not valid throw new Exception($email); } } catch(Exception $e) { //re-throw exception throw new customException($email); } } catch (customException $e) { //display custom message echo $e->errorMessage(); } ?>
例子解释: 上面的代码检测在邮件地址中是否含有字符串 "example"。如果有,则再次抛出异常:
customException() 类是作为旧的 exception 类的一个扩展来创建的。这样它就继承了旧类的所有属性和方法。 创建 errorMessage() 函数。如果 e-mail 地址不合法,则该函数返回一个错误消息。 把 $email 变量设置为一个有效的邮件地址,但含有字符串 "example"。 "try" 代码块包含另一个 "try" 代码块,这样就可以再次抛出异常。 由于 e-mail 包含字符串 "example",因此触发异常。 "catch" 捕获到该异常,并重新抛出 "customException"。 捕获到 "customException",并显示一条错误消息。 如果在其目前的 "try" 代码块中异常没有被捕获,则它将在更高层级上查找 catch 代码块。 设置顶层异常处理器 (Top Level Exception Handler) set_exception_handler() 函数可设置处理所有未捕获异常的用户定义函数。
getMessage(); } set_exception_handler('myException'); throw new Exception('Uncaught Exception occurred'); ?>
以上代码的输出应该类似这样: Exception: Uncaught Exception occurred 在上面的代码中,不存在 "catch" 代码块,而是触发顶层的异常处理程序。应该使用此函数来捕获所有未被捕获的异常。
异常的规则 需要进行异常处理的代码应该放入 try 代码块内,以便捕获潜在的异常。 每个 try 或 throw 代码块必须至少拥有一个对应的 catch 代码块。 使用多个 catch 代码块可以捕获不同种类的异常。 可以在 try 代码块内的 catch 代码块中再次抛出(re-thrown)异常。
简而言之:如果抛出了异常,就必须捕获它。