例外(exceptions)

目次

PHP は、他のプログラミング言語に似た例外モデルを有しています。 PHP 内で例外が投げられ (throw され)、それが 捕捉され (catch され) ます。発生した例外を 捕捉するには、コードを try ブロックで囲みます。 各 try ブロックには、対応する catch ブロックあるいは finally ブロックが存在する必要があります。

スローされるオブジェクトは、Exception クラスあるいは Exception のサブクラスのインスタンスでなければなりません。 それ以外のオブジェクトをスローしようとすると PHP の Fatal Error が発生します。

catch

さまざまな型の例外を捕捉するために 複数の catch フロックを使用することができます。 通常の実行時 (try ブロック内で例外が投げられなかった 場合) は、catch ブロック内は処理されず、それ以降から処理が続けられます。 catch ブロックの中から例外を throw する (あるいは throw しなおす) こともできます。

例外が投げられた場合、その命令に続くコードは実行されず、 PHP は最初にマッチする catch ブロックを探します。 例外が捕捉されない場合、PHP は "Uncaught Exception ..." というメッセージとともに 致命的なエラー(fatal error)を発行します。 ただし、set_exception_handler() でハンドラが 定義されている場合を除きます。

PHP 7.1 以降では、catch ブロック で 複数の例外を パイプ文字 (|) を使って指定できるようになりました。 これは、異なるクラス改装からの例外を同時に扱う必要がある場合に有用です。

finally ブロックと return 文の間には注意すべき相互作用があります。 return 文が trycatch ブロックの内部に存在した場合でも、 finally ブロックは実行されます。 さらに、return 文は出現した時に評価されますが、 結果は finally ブロックが実行された後に返されます。 さらに、finally ブロックにも return 文が存在した場合は、 finally ブロックから値が返されます。

finally

PHP 5.5 以降では、catch ブロックの後に finally ブロックも指定できるようになりました。 finally ブロックの何かに書いたコードは、 try および catch ブロックの後で常に実行されます。 例外がスローさされたかどうかには関係ありません。

注意

注意:

PHP の内部関数の多くは エラー報告 を使っており、例外を使っているのは新しい オブジェクト指向 の拡張モジュールのみです。 しかし、ErrorException を使えば簡単にエラーを例外に変換することができます。

ヒント

Standard PHP Library (SPL) には組み込みの例外が数多く用意されています。

例3 例外を投げるには

<?php
function inverse($x) {
    if (!
$x) {
        throw new 
Exception('ゼロによる除算。');
    }
    return 
1/$x;
}

try {
    echo 
inverse(5) . "\n";
    echo 
inverse(0) . "\n";
} catch (
Exception $e) {
    echo 
'捕捉した例外: ',  $e->getMessage(), "\n";
}

// 実行は継続される
echo "Hello World\n";
?>

上の例の出力は以下となります。

0.2
捕捉した例外: ゼロによる除算。
Hello World

例4 例外処理での finally ブロック

<?php
function inverse($x) {
    if (!
$x) {
        throw new 
Exception('ゼロによる除算。');
    }
    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\n";
?>

上の例の出力は以下となります。

0.2
First finally.
捕捉した例外: ゼロによる除算。
Second finally.
Hello World

例5 finally ブロックと return の相互作用

<?php

function test() {
    try {
        throw new 
Exception('foo');
    } catch (
Exception $e) {
        return 
'catch';
    } finally {
        return 
'finally';
    }
}

echo 
test();
?>

上の例の出力は以下となります。

finally

例6 ネストした例外

<?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!"

例7 複数の例外ハンドリングをひとつの catch で行う

<?php

class MyException extends Exception { }

class 
MyOtherException extends Exception { }

class 
Test {
    public function 
testing() {
        try {
            throw new 
MyException();
        } catch (
MyException MyOtherException $e) {
            
var_dump(get_class($e));
        }
    }
}

$foo = new Test;
$foo->testing();

?>

上の例の出力は以下となります。

string(11) "MyException"
add a note add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top