PHP 5 は、他のプログラミング言語に似た例外モデルを有しています。 PHP 内で例外が投げられ ("throw" され)、それが 捕捉され ("catch" され) ます。発生した例外を 捕捉するには、コードを try ブロックで囲みます。 各 try ブロックには、対応する catch ブロックが存在する必要があります。異なる型の例外を捕捉するために 複数の catch フロックを使用することができます。 通常の実行時 (try ブロック内で例外が投げられなかった 場合、あるいは投げられた例外に対応する catch ブロックが存在しなかった場合) は、catch ブロック内は処理されず、それ以降から処理が続けられます。 catch ブロックの中から例外を投げる (あるいは投げなおす) こともできます。
例外が投げられた場合、その命令に続くコードは実行されず、 PHP は最初にマッチする catch ブロックを探します。 例外が捕捉されない場合、PHP は "Uncaught Exception ..." というメッセージとともに 致命的なエラー(fatal error)を発行します。 ただし、 set_exception_handler() でハンドラが 定義されている場合を除きます。
PHP 5.5 以降では、catch ブロックの後に finally ブロックも指定できるようになりました。 finally ブロックの何かに書いたコードは、 try および catch ブロックの後で常に実行されます。 例外がスローさされたかどうかには関係ありません。 finally ブロックを実行してから、通常の処理を続行します。
スローされるオブジェクトは、Exception クラスあるいは Exception のサブクラスのインスタンスでなければなりません。 それ以外のオブジェクトをスローしようとすると PHP の Fatal Error が発生します。
注意:
PHP の内部関数の多くは エラー報告 を使っており、例外を使っているのは新しい オブジェクト指向 の拡張モジュールのみです。 しかし、ErrorException を使えば簡単にエラーを例外に変換することができます。
Standard PHP Library (SPL) には組み込みの例外が数多く用意されています。
例1 例外を投げるには
<?php
function inverse($x) {
if (!$x) {
throw new Exception('ゼロによる除算。');
}
else return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo '捕捉した例外: ', $e->getMessage(), "\n";
}
// 実行は継続される
echo 'Hello World';
?>
上の例の出力は以下となります。
0.2 捕捉した例外: ゼロによる除算。 Hello World
例2 例外処理での finally ブロック
<?php
function inverse($x) {
if (!$x) {
throw new Exception('ゼロによる除算。');
}
else return 1/$x;
}
try {
echo inverse(5) . "\n";
} catch (Exception $e) {
echo '捕捉した例外: ', $e->getMessage(), "\n";
} finally {
echo "First finally.\n";
}
try {
echo inverse(0) . "\n";
} catch (Exception $e) {
echo '捕捉した例外: ', $e->getMessage(), "\n";
} finally {
echo "Second finally.\n";
}
// 処理を続行します
echo 'Hello World';
?>
上の例の出力は以下となります。
0.2 First finally. 捕捉した例外: ゼロによる除算。 Second finally. Hello World
例3 ネストした例外
<?php
class MyException extends Exception { }
class Test {
public function testing() {
try {
try {
throw new MyException('foo!');
} catch (MyException $e) {
/* 改めてスロー */
throw $e;
}
} catch (Exception $e) {
var_dump($e->getMessage());
}
}
}
$foo = new Test;
$foo->testing();
?>
上の例の出力は以下となります。
string(4) "foo!"