カテゴリー:
例外処理
閲覧数:915 配信日:2014-03-12 20:42
tryブロックの外
try~catch未利用
・set_exception_handler関数を利用(Exceptionクラスは利用しているものの、try~catchは利用せず、例外を明示的に投げているだけ)
・set_exception_handler関数では、例外が捕捉されなかった場合のデフォルトの例外ハンドラを指定することができる
・下記の例では、tryブロックの外で例外を投げているため、通常はFatal errorとなるが、set_exception_handler()で例外ハンドラを指定しているため、exceptionHandler関数が呼ばれている
・注意すべき点として、例外ハンドラの処理後にPHPプログラムは実行を終了してしまう
function exceptionHandler($e)
{
echo $e->getMessage(), PHP_EOL;
}
set_exception_handler('exceptionHandler');
throw new Exception('catchされなかった例外');
echo 'end', PHP_EOL;
// 出力:catchされなかった例外
・結果
catchされなかった例外
ファイルオープン
Warning:エラー(ファイルオープンエラー)のエラーハンドリング
function test_error_handler($errorno,$errstr,$errfile,$errline,$errcontext) {
switch ($errno) {
case E_ERROR://ユーザ定義関数では、E_ERRORは扱えない
echo "致命的エラー:" . $errorno . " ユーザー作成エラーメッセージ:" . $errstr. " エラー発生行数:" . $errline."<br />";
break;
default:
echo "その他のエラー エラーコード:" . $errorno . "<br> ユーザー作成エラーメッセージ:" . $errstr . "<br> エラー発生行数:" . $errline."<br>";
break;
}
}
set_error_handler("test_error_handler");
$fd = fopen("c:/temp/azz.txt","r");
・結果
その他のエラー エラーコード:2
ユーザー作成エラーメッセージ:fopen(c:/temp/azz.txt): failed to open stream: No such file or directory
エラー発生行数:34
ユーザー作成エラーメッセージ:fopen(c:/temp/azz.txt): failed to open stream: No such file or directory
エラー発生行数:34
0除算
Warning:エラー(0 除算)のエラーハンドリング
・エラータイプにE_ALL引数を指定
function my_error_handler ( $errno, $errstr, $errfile, $errline, $errcontext ) {
echo "[$errno] $errstr ($errline)行目\n";
}
set_error_handler( 'my_error_handler', E_ALL );
$i = 5/0;
・結果
[2] Division by zero (29)行目
try~catch利用
・set_error_handler()の引数で指定したメソッドで、Exceptionを継承した例外クラスのインスタンスオブジェクトをスロー
・1.tryブロック内の処理でエラー発生
・2.発生したエラーは、「set_error_handler()の引数で指定したメソッド」で処理
・3.同メソッドより、「Exceptionを継承した例外クラスのインスタンスオブジェクト」をスロー
・4.例外キャッチ
function errorHandler($errno, $errstr, $errfile, $errline) {
throw new Exception($errstr, $errno);//3.例外をスロー
}
set_error_handler('errorHandler');//2.エラーを「引数で指定した関数」で処理
try {
5/0;//1.… 0除算。Warningエラー発生
} catch (Exception $e) {//4.例外をキャッチ
echo $e->getMessage();
}
・処理結果
Division by zero
・set_error_handler()は、Warning:エラー(0 除算)をエラーハンドリング出来るが、Fatal error: エラー(未定義関数呼び出し/致命的かつ復帰できない場合)は、エラーハンドリング出来ない。これは Fatal error (致命的エラー) の箇所で、スクリプトが終了処理してしまい、ユーザー定義のエラーハンドラ関数が呼び出されないため
function my_error_handler ( $errno, $errstr, $errfile, $errline, $errcontext ) {
// echo "[$errno] $errstr $errfile($errline)\n";
echo "[$errno] $errstr ($errline)\n";
}
//set_error_handlerがない状態
$i = 5/0;//0 除算でエラー発生→Warning:
//foo();//未定義関数でエラー発生→Fatal error:ここで処理終了するため、コメントアウト
set_error_handler( 'my_error_handler', E_ALL );
$i = 5/0;//0 除算でエラー発生→Warning:
foo();//未定義関数でエラー発生→Fatal error:ここで処理終了
上記のようなエラーハンドラ関数で処理できないエラーについては、スクリプトのシャットダウン関数を利用して処理。シャットダウン関数は register_shutdown_function 関数で指定
クラス
echo 'phpversion : ' . phpversion() . "\n<br>";
//
// PHPエラーを例外(Exception)へ変換
//
class MyException extends Exception
{
public function __construct($errno, $errstr, $errfile, $errline)
{
p($errno ); //8…エラー出力レベル(ビット値)
p($errstr ); //Undefined variable: xxx
//p($errfile ); //エラーファイル
p($errline ); //エラー行数
// エラー定数(エラー出力レベル/ビット値)と文字列のマッピング(連想配列)
$errlev = array(
E_USER_ERROR => 'FATAL',
E_ERROR => 'FATAL',
E_USER_WARNING => 'WARNING',
E_WARNING => 'WARNING',
E_USER_NOTICE => 'NOTICE',
E_NOTICE => 'NOTICE',
E_STRICT => 'E_STRICT'
);
p($errlev );
/*出力
Array
(
[256] => FATAL
[1] => FATAL
[512] => WARNING
[2] => WARNING
[1024] => NOTICE
[8] => NOTICE
[2048] => E_STRICT
)
*/
$add_msg= (string)$errno;//8
p($errlev[$errno]);//NOTICE…取得した「ビット値」を、用意した連想配列のキーへ対応させ、値を取得
if (isset($errlev[$errno])) {
$add_msg = $errlev[$errno] . ' : ';
}
parent::__construct($add_msg . $errstr, $errno);//(エラー定数+)エラーメッセージ,例外コード
$this->file = $errfile;//プロパティへのセッター
$this->line = $errline;//プロパティへのセッター
}
}
function errorHandler($errno, $errstr, $errfile, $errline)
{
throw new MyException($errno, $errstr, $errfile, $errline);
}
set_error_handler('errorHandler');
//
// 以下テストコード
//
error_reporting(E_ALL|E_STRICT);//E_ALL+E_STRICT
function funcA()
{
echo $xxx; // 意図的に、未定義の変数を参照しNOTICEを発生させる
}
try {
funcA();
}
catch (Exception $e) {
echo "--------------\n<br><pre>";
echo $e . "</pre>\n<br>";
echo "--------------\n<br>";
}
/*出力
phpversion : 5.3.8
8
Undefined variable: xxx
85
Array
(
[256] => FATAL
[1] => FATAL
[512] => WARNING
[2] => WARNING
[1024] => NOTICE
[8] => NOTICE
[2048] => E_STRICT
)
NOTICE
--------------
exception 'MyException' with message 'NOTICE : Undefined variable: xxx' in /○○/exception/13.php:85
Stack trace:
#0 /○○/exception/13.php(85): errorHandler(8, 'Undefined varia...', '/○○/ibj/pu...', 85, Array)
#1 /○○/exception/13.php(89): funcA()
#2 {main}
*/