English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
このチュートリアルでは、PHPで例外を発生させたりキャッチしたりする方法を学びます。
例外は、何らかの異常事象やエラーが発生したことを示すシグナルです。例えば、データベースの接続やクエリの失敗、アクセスしようとしたファイルが存在しないなど、さまざまな理由で例外が発生する可能性があります。
PHPは強力な例外処理メカニズムを提供しており、エラーを美しく処理する方法を提供します。PHPの伝統的なエラーハンドリングシステムとは対照的に、例外処理はエラーを処理するための手段ですオブジェクト指向の方法により、より特定性と柔軟性のあるエラーレポート形式を提供します。例外モデルはPHPで最初にPHP 5で導入されました。
例外を基にした方法では、コードはtryブロックに書かれ、tryブロック内で例外が発生した場合、throw文を使って例外を発生させます。その後、1つまたは複数のcatchブロックでキャッチされ、解析されます。
以下の例では、例外処理がどのように動作するかを示します:
<?php function division($dividend, $divisor) { //除数が0の場合は、例外を投げます if($divisor == 0) { throw new Exception('0で割り算'); } else { $quotient = $dividend / $divisor; echo "<p>$dividend / $divisor = $quotient </p>"; } } try{ division(10, 2); division(30, -4); division(15, 0); //例外が発生した場合、その後の行は実行されません echo '<p>すべての処理が成功しました。<'/p>'; } catch(Exception $e){ //例外を処理します echo "<p>キャッチした例外: " . $e->getMessage() . "</p>"; } // 実行を続けます echo "<p>Hello World!/p>"; ?>
このコードが何についてのものかご存知でしょうか。いいですね、このコードの各部分を一つずつ説明し、よりよく理解するために逐次確認しましょう。
PHPの例外処理システムには、try、throw、catch、およびExceptionクラスの四つの基本部分があります。以下のリストでは、各部分の動作原理を説明します。
上記のdivision()関数は、除数がゼロかどうかをチェックします。もしゼロであれば、PHPのthrow文を使って例外を投げます。そうでない場合、この関数は指定された数字で除法を行い、結果を表示します。
tryブロックで異なるパラメータを使用してdivision()関数を呼び出します。tryブロック内でコードを実行中に例外が発生すると、PHPはそのポイントで実行を停止し、対応するcatchブロックを探します。catchブロックが見つかった場合、catchブロック内のコードを実行します。そうでない場合、致命的なエラーが生成されます。
catchブロックは通常、tryブロックで投げられた例外をキャッチし、例外情報を含むオブジェクト($e)を作成します。このオブジェクトからエラーメッセージを取得するには、例外のgetMessage()メソッドを使用できます。
PHPの例外クラスにはgetCode()、getFile()、getLine()、getTraceAsString()などのメソッドが提供されており、詳細なデバッグ情報を生成するために使用できます。
<?php //デフォルトのエラーレポートを無効にします error_reporting(0); try{ $file = "somefile.txt"; //ファイルを開こうと試みます $handle = fopen($file, "r"); if(!$handle){ throw new Exception("ファイルを開けられません!", 5); } //ファイル内容を読み込もうと試みます $content = fread($handle, filesize($file)); if(!$content){ throw new Exception("Could not read file!", 10); } //ファイルハンドルを閉じる fclose($handle); //ファイル内容を表示 echo $content; } catch(Exception $e){ echo "<h3>Caught Exception!/h3>"; echo "<p>Error message: " . $e->getMessage() . "</p>"; echo "<p>File: " . $e->getFile() . "</p>"; echo "<p>行: " . $e->getLine() . "</p>"; echo "<p>エラーコード: " . $e->getCode() . "</p>"; echo "<p>トレース: " . $e->getTraceAsString() . "</p>"; } ?>
例外のコンストラクタは、例外メッセージと例外コードを受け取ることができます。例外メッセージは通常、エラーの原因を示す一般的な情報として使用されますが、例外コードはエラーを分類するために使用されます。後でExceptionのgetCode()メソッドを使用して提供された例外コードを取得することができます。
ヒント:例外は特殊な状況を表すためにのみ使用されるべきであり、正常なアプリケーションフローを指定するために使用されるべきではありません。特定の場所でスクリプトの他の場所にジャンプすることは、アプリケーションのパフォーマンスに悪影響を与えることがあります。
さらに、カスタム例外ハンドラを定義して、異なるタイプの例外を異なる方法で処理できます。これにより、各例外タイプに対して独立したcatchブロックを使用することができます。
Exceptionクラスを拡張することで、カスタム例外を定義できます。Exceptionはすべての例外の基底クラスです。カスタム例外クラスはPHP Exceptionクラスのすべての属性とメソッドを継承します。また、カスタムメソッドをカスタム例外クラスに追加することもできます。以下の例を見てみましょう:
<?php //Exceptionクラスを拡張します class EmptyEmailException extends Exception {} class InvalidEmailException extends Exception {} $email = "[email protected]"; try{ //メールアドレスが空の場合、例外を投げます if($email == ""){ throw new EmptyEmailException("<p>メールアドレスを入力してください!</p> } //メールが無効な場合、例外を投げます if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) { throw new InvalidEmailException("<p><b>$email</b> 有効なメールアドレスではありません!/p> } // メールが有効な場合、成功メッセージを表示します echo "<p>成功:メールの確認が成功しました.</p>"; catch(EmptyEmailException $e){ echo $e->getMessage(); catch(InvalidEmailException $e){ echo $e->getMessage(); } ?>
上記の例では、Exceptionの基底クラスから2つの新しい例外クラスを派生させました:EmptyEmailExceptionおよびInvalidEmailException複数のキャッチブロックを使用して、生成された例外の種類に応じて異なるエラーメッセージを表示します。
これらのカスタム例外クラスはExceptionクラスの属性とメソッドを継承しているため、getMessage()、getLine()、getFile()などの例外クラスメソッドを使用して、例外オブジェクトのエラーデータを取得できます。
本章の前半部分で説明したように、未捕獲の例外が発生した場合、PHPは致命的なエラーを生成し、「Uncaught Exception ...」メッセージを含むエラーメッセージを生成します。 このエラーメッセージには、問題が発生したファイル名や行番号などの機密情報が含まれている可能性があります。 このような情報をユーザーに公開したくない場合は、カスタム関数を作成し、set_exception_handler()関数にその関数を登録してすべての未捕獲の例外を処理することができます。
<?php function handleUncaughtException($e){ //ユーザーに一般的なエラーメッセージを表示します echo "哎呀!出了点问题。请重试,如果问题仍然存在,请与我们联系。"; // エラーストリングを構築します $error = "Uncaught Exception: " . $message = date("Y-m-d H:i:s - "); $error .= $e->getMessage() . " in file " . $e->getFile() . " on line " . $e->getLine() . "\n"; //ファイルにエラーデータの詳細を記録します error_log($error, 3, "var/log/exceptionLog.log"); } //カスタム例外処理プログラムを登録します set_exception_handler("handleUncaughtException"); // 例外を投げます throw new Exception("Testing Exception!"); ?>
注意:未捕获的异常总是会导致脚本终止。 したがって、スクリプトが例外が発生したポイントの後で続行するように希望する場合、それぞれのtryブロックには少なくとも1つの対応するcatchブロックが必要です。