はじめに
前回の記事では、PHPのコールバック関数について紹介しました。
前回の記事
本記事では、PHPのエラーと例外について紹介します。
PHPのエラー
エラーが発生したときの挙動
PHPでは実行中にエラーが発生しても、基本的には処理を続けようとします。ただし、続行できないFatal error(致命的なエラー)が発生した場合は処理を停止します。
例えば、次の例では「Warning(警告)」と「Fatal error(致命的なエラー)」を発生させています。
[エラーの例]
<?php
// 警告のエラーを発生させる(存在しないファイルを指定)
$fd = fopen("c:/temp/abc.txt","r");
echo "継続処理";
// 致命的なエラーを発生させる(存在しない関数を呼び出す)
a();
echo "継続処理";
?>
[実行結果]
Warning: fopen(c:/temp/abc.txt): Failed to open stream: No such file or directory in C:\xampp\htdocs\phpSample\lesson22\errorHandlerSample.php on line 4
継続処理
Fatal error: Uncaught Error: Call to undefined function a() in C:\xampp\htdocs\phpSample\lesson22\errorHandlerSample.php:9 Stack trace: #0 {main} thrown in C:\xampp\htdocs\phpSample\lesson22\errorHandlerSample.php on line 9
Warning(警告)の場合は、エラーメッセージを表示し処理を継続していますが、Fatal error(致命的なエラー)の場合は、継続処理を行わず処理を停止しています。
スポンサーリンク
このエラーの発生を感知して、何らかの処理を行うことをエラーハンドリングといいます。エラーハンドリングを行うには「set_error_handler()」関数を使用します。(ただし、Fatal errorはハンドリングしない)
set_error_handler関数の使い方
「set_error_handler()」関数を使用することで、エラーハンドリングを行うことができます。
[set_error_handler関数の使用例]
<?php
// エラー時の処理を登録
set_error_handler(function($errno, $errstr, $errfile, $errline){
print "エラーが発生しました。$errno, $errstr <br />";
});
// 警告のエラーを発生させる(存在しないファイルを指定)
$fd = fopen("c:/temp/abc.txt","r");
?>
[実行結果]
エラーが発生しました。2, fopen(c:/temp/abc.txt): Failed to open stream: No such file or directory
PHPの例外
プログラム実行中に発生する予期せぬエラーのことを例外(Exception)といいます。
例外処理の流れ
例外が発生しそうな処理には、try文、catch文、finally文を使います。
try{}内に例外が発生しそうな処理を記述します。
そして、catch{}内には例外が発生した時に行う処理を記述します。try{}内で例外が発生した場合、catch{}内の処理が動き出し、catchでは例外クラスのオブジェクトを受け取ります。例外クラスのオブジェクトには、どんな例外がどこで発生したのかの情報が格納されています。
最後に、finally{}内の処理は例外発生の有無に関わらず行う処理を記述します。finally文は省略可能なので、必要がなければ書かなくて大丈夫です。
正常時の流れ
- try内の処理を実行
- finally内の処理を実行(finallyは省略可能なのでfinallyが存在する場合のみ実行)
例外発生時の流れ
- try内の処理を実行
- 例外発生(例外が発生した時点でtry内の処理は中断しcatch文へ)
- catch内の処理を実行
- finally内の処理を実行(finallyは省略可能なのでfinallyが存在する場合のみ実行)
スポンサーリンク
try-catchの実装例
それでは、実際にソースコードで try-catch の使用例を紹介します。
PHPでは throw された例外(Exception)しか catch できません。(ただのエラーは catchできない)
[エラーをcatchできないケース]
<?php
try {
// 警告のエラーを発生させる(存在しないファイルを指定)
$fd = fopen("c:/temp/abc.txt","r");
} catch (Exception $e) {
echo "例外が発生しました。".$e->getMessage();
}
?>
[実行結果]
Warning: fopen(c:/temp/abc.txt): Failed to open stream: No such file or directory in C:\xampp\htdocs\phpSample\lesson22\tryCatchSample.php on line 5
例外ではない ただのエラーをcatchするためには、「set_error_handler()」関数を使用します。エラーを「set_error_handler()」関数でハンドリングし、「set_error_handler()」関数内で例外を発生させます。
[try-catchの実装例]
<?php
// エラー時に例外をスローするように登録
set_error_handler(function($errno, $errstr, $errfile, $errline) {
if (!(error_reporting() & $errno)) {
return;
}
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
});
try {
// 警告のエラーを発生させる(存在しないファイルを指定)
$fd = fopen("c:/temp/abc.txt","r");
} catch (Exception $e) {
echo "例外が発生しました。".$e->getMessage();
}
?>
[実行結果]
例外が発生しました。fopen(c:/temp/abc.txt): Failed to open stream: No such file or directory
エラー発生時の流れ
- try内の処理を実行
- エラー発生(エラーが発生したのでset_error_handler()で登録した関数へ)
- set_error_handler() で登録した関数の処理を実行(関数内で例外を発生させる。例外が発生したのでcatch文へ)
- catch内の処理を実行
- finally内の処理を実行(finallyは省略可能なのでfinallyが存在する場合のみ実行)