PHP Try Catch の例: 例外とエラー処理のチュートリアル
⚡ スマートサマリー
PHPにおけるエラー処理と例外処理は、生のエラーをそのまま公開するのではなく、予期せぬ状況を適切に管理することで、アプリケーションの安定性とセキュリティを維持します。このチュートリアルでは、エラーと例外の違い、die文、カスタムエラーハンドラ、エラー報告レベル、そして複数の例外タイプに対応したtry、throw、catch例外モデルについて説明します。

例外とは何ですか?
エラーとは、プログラム自体では処理できない、予期しないプログラムの結果です。
エラーはプログラムを修正することで解決されます。 エラーの例としては、実行が決して停止しない無限ループが挙げられます。
例外とは、プログラム自体が処理できる予期せぬプログラム結果のことである。
例外の例としては、存在しないファイルを開こうとした場合などが挙げられる。
この例外は、ファイルを作成するか、ユーザーにファイルの検索オプションを提示することで処理できます。
例外処理を行う理由とは?
- エンドユーザーにとって非常に迷惑または不快な結果となる可能性のある、予期せぬ結果が当社のページで発生しないようにします。
- 悪意のあるユーザーがアプリケーションを攻撃するために使用する可能性のある情報を公開しないことで、アプリケーションのセキュリティを向上させます。
- PHPの例外処理は、予測可能なエラーが発生した場合に、プログラムの通常の流れを変更するために使用されます。
PHPエラー処理
エラーが発生した場合、構成設定に応じて、 PHP 発生したエラーに関連する情報を含むエラー メッセージを Web ブラウザに表示します。
PHPにはエラーを処理するための様々な方法が用意されています。ここでは、よく使われる3つの方法を見ていきましょう。
- ダイステートメント die関数は、echo関数とexit関数を一つにまとめたものです。エラーが発生した際にメッセージを出力し、スクリプトの実行を停止したい場合に非常に便利です。
- カスタムエラーハンドラ – これらは、エラーが発生するたびに呼び出されるユーザー定義関数です。
- PHPエラーレポート エラーメッセージは、PHPのエラー報告設定によって異なります。この方法は、エラーの原因が全く分からない開発環境で非常に役立ちます。表示される情報は、アプリケーションのデバッグに役立ちます。
エラー処理の例
それでは、エラー処理ルーチンを用いた簡単な例をいくつか見ていきましょう。
計算式で数値をゼロで割ってしまう可能性があると仮定しましょう。PHPが生のエラーを表示するのではなく、そのようなケースを適切に処理したいと考えます。
以下のコードは上記の例を実装しています。
<?php
$denominator = 0;
echo 2 / $denominator;
?>
simple_error.php ファイルを phptuts フォルダに保存したと仮定して、 URL http://localhost/phptuts/simple_error.php
以下の結果が得られます。
上記の結果からわかるように、アプリケーションがプロフェッショナルに見えず、ユーザーにとって煩わしいものになる可能性があります。
上記のコードを修正し、アプリケーションのエラーハンドラを作成します。
<?php $denominator = 0; if ($denominator != 0) { echo 2 / $denominator; } else { echo "cannot divide by zero (0)"; } ?>
上記のコードを error_handling.php として保存したと仮定して、 URL http://localhost/phptuts/error_handling.php
注意: 「ファイルが見つかりません」のような生のメッセージを表示する代わりに、上記のようなメッセージを表示することは、セキュリティ上の良い対策です。
カスタムエラーハンドラーを使用する別の例を見てみましょう。
カスタム エラー ハンドラーはデフォルトの PHP エラー処理関数として設定され、基本的にエラー番号とメッセージを表示します。
以下のコードは、上記の例の実装を示しています。
<?php function my_error_handler($error_no, $error_msg) { echo "Oops, something went wrong:"; echo "Error number: [$error_no]"; echo "Error Description: [$error_msg]"; } set_error_handler("my_error_handler"); echo (5 / 0); ?>
Video Cloud Studioで URL http://localhost/phptuts/custom_error_handler.php以下のような結果が得られます。
上記の例からもわかるように、カスタムエラーハンドラーは次のような点で強力です。
- これらを使用すると、エラー メッセージをカスタマイズできます。
- カスタムエラーハンドラーには、ファイルやデータベースへのエラーログ記録、開発者へのメール送信、その他同様の処理を含めることもできます。
それでは、3つ目のエラー処理方法を見ていきましょう。ここでは、PHPに組み込まれているerror_reporting関数を使用します。基本的な構文は以下のとおりです。
<?php error_reporting($reporting_level); ?>
ここに、
- 「error_reporting」はPHPのエラー報告関数です。
- 「$reporting_level」はオプションであり、レポートレベルを設定するために使用できます。レポートレベルが指定されていない場合、PHPはphp.iniファイルで指定されているデフォルトのエラーレポートレベルを使用します。
| 報告レベル | 詳細説明 | 例: |
|---|---|---|
| E_警告 | 警告メッセージのみを表示します。 スクリプトの実行を停止しません | エラー報告(E_WARNING); |
| E_NOTICE | プログラムの通常の実行中に発生する可能性のある通知、またはエラーの可能性がある通知を表示します。 | error_reporting(E_NOTICE); |
| E_USER_ERROR | ユーザーが生成したエラー、つまりカスタムエラーハンドラーを表示します。 | error_reporting(E_USER_ERROR); |
| E_USER_WARNING | ユーザーが生成した警告メッセージを表示します | エラー報告(E_USER_WARNING); |
| E_USER_NOTICE | ユーザーが作成した通知を表示します | エラー報告(E_USER_NOTICE); |
| E_RECOVERABLE_ERROR | 致命的ではないエラーを表示し、カスタムエラーハンドラを使用して処理できます。 | エラー報告(E_RECOVERABLE_ERROR); |
| E_ALL | すべてのエラーと警告を表示します | エラー報告(E_ALL); |
エラーと例外の違い
- 例外はスローされ、捕捉されることを前提としているが、エラーは一般的に回復不可能である。
- 例外処理はオブジェクト指向的に行われます。つまり、例外が発生すると、例外の詳細を含む例外オブジェクトが作成されます。
下の表は、例外オブジェクトのメソッドを示しています。
| 方法 | 詳細説明 | 例: |
|---|---|---|
| getMessage() | 例外のメッセージを表示します |
<?php
echo $e->getMessage();
?>
|
| 取得するCode() | 例外を表す数値コードを表示します。 |
<?php
echo $e->getCode();
?>
|
| getFile() | 例外が発生したファイル名とパスを表示します |
<?php
echo $e->getFile();
?>
|
| getLine() | 例外が発生した行番号を表示します |
<?php
echo $e->getLine();
?>
|
| 取得するTrace() | 背面の配列を表示しますtrac例外の前の e |
<?php print_r( $e->getTrace()); ?> |
| getPrevious() | 現在の例外の前に前の例外を表示します |
<?php
echo $e->getPrevious();
?>
|
| 取得するTraceAsString() | 背面を表示しますtrac例外を配列ではなく文字列として扱う |
<?php
echo $e->getTraceAsString();
?>
|
| __toString() | 例外全体を文字列として表示します |
<?php
echo $e->__toString();
?>
|
以下は例外をスローするための基本的な構文です。
<?php throw new Exception("This is an exception example"); ?>
ここに、
- 「throw」は例外をスローするために使用されるキーワードです
- 「new Exception(…)」は例外オブジェクトを作成し、「これは例外の例です」という文字列をメッセージパラメータとして渡します。
上記のコードは次のメッセージを出力します。
次に、例外処理(throwとcatch)を実装した例を見ていきましょう。上記の例を修正し、try、throw、catchを追加します。
基本的な構文は次のとおりです。
<?php try { // code goes here that could potentially throw an exception } catch (Exception $e) { // exception handling code goes here } ?>
ここに、
- 「try{…}」は、例外が発生する可能性がある実行されるコードのブロックです。
- 「catch(Exception $e){…}」は、スローされた例外をキャッチし、例外オブジェクトを変数 $e に割り当てるコード ブロックです。
以下のコードは、try、throw、catch を実装した基本的な例外処理の例を示しています。このプログラムは意図的に例外をスローし、それをキャッチします。
<?php try { $var_msg = "This is an exception example"; throw new Exception($var_msg); } catch (Exception $e) { echo "Message: " . $e->getMessage(); echo ""; echo "getCode(): " . $e->getCode(); echo ""; echo "__toString(): " . $e->__toString(); } ?>
Video Cloud Studioで URL http://localhost/phptuts/exception_handling.php以下のような結果が得られます。
また、発生した例外の種類に応じて、1つのPHP try文に対して複数の例外を作成することも可能です。
に関する記事を参照してください MySQLPHP による複数例外の実装例のためのデータアクセス。
複数の例外
複数の例外は、複数の catch ブロックを使用してスローされた例外を処理します。複数の例外は、次のような場合に役立ちます。
- スローされた例外に応じてカスタマイズされたメッセージを表示したい
- スローされた例外に応じて固有の操作を実行したい
以下のフローチャートは、複数の例外処理がどのように機能するかを示しています。
複数の例外処理を用いる例を見てみましょう。渡された分母で数値を割るコードを修正します。
想定される例外は2種類あります。
- ゼロ除算
- 負の数による除算
簡潔にするため、catch ブロックでは例外の種類のみを表示します。例外をスローするには、PHP の組み込みクラスである Exception クラスを使用します。ここでは、Exception クラスを継承する 2 つのクラスを作成し、それらを使用して例外をスローします。
以下のコードは実装を示しています。
<?php class DivideByZeroException extends Exception {}; class DivideByNegativeException extends Exception {}; function process($denominator) { try { if ($denominator == 0) { throw new DivideByZeroException(); } else if ($denominator < 0) { throw new DivideByNegativeException(); } else { echo 25 / $denominator; } } catch (DivideByZeroException $ex) { echo "DIVIDE BY ZERO EXCEPTION!"; } catch (DivideByNegativeException $ex) { echo "DIVIDE BY NEGATIVE NUMBER EXCEPTION!"; } catch (Exception $x) { echo "UNKNOWN EXCEPTION!"; } } process(0); ?>
コードのテスト
multiple_exceptions.php は phptuts フォルダに保存済みであると仮定します。
を参照 URL http://localhost/phptuts/multiple_exceptions.php
PHP ファイルに戻り、次の図に示すように、パラメータとして -1 を渡します。
を参照 URL http://localhost/phptuts/multiple_exceptions.phpどのような結果が得られますか?次に、パラメータとして3を渡してください。どのような結果が得られますか?
最後にブロックとPHP 7エラーモデル
最新のPHPでは、上記のモデルに2つの重要な要素が追加されています。finallyブロックは、例外がスローされたかどうかに関わらず、tryとcatchの後に実行されるため、ファイルやデータベース接続を閉じるなどのクリーンアップ処理に最適です。
PHP 7以降、以前は致命的エラーとされていた多くのエラーがErrorオブジェクトとしてスローされるようになりました。ExceptionとErrorはどちらもThrowableインターフェースを実装しているため、catch(\Throwable $e)ブロックでどちらのエラーも処理できます。
<?php try { $result = 10 / 0; } catch (DivisionByZeroError $e) { echo "Caught: " . $e->getMessage(); } finally { echo "This message always runs"; } ?>
ここでは、PHP 8 ではゼロ除算を行うと DivisionByZeroError が発生し、catch ブロックがそれを報告し、finally ブロックは常に実行され、エラーが発生したかどうかに関わらずそのメッセージが出力されます。








