例外処理 (PHP 7の変更点など)
Q. catch(PDOException $e) {と catch (Exception $e)ではどう違うの?
A. `catch(PDOException $e)`と`catch(Exception $e)`は、例外をキャッチするための構文ですが、キャッチする例外のタイプに違いがあります。
`catch(PDOException $e)`:
この構文は、`PDOException`タイプの例外だけをキャッチします。
`PDOException`は、PHPのPDO拡張モジュールに関連するエラーを表すクラスです。PDOを使用してデータベース操作を行う際にエラーが発生した場合(例: 接続エラーやクエリエラーなど)、このタイプの例外がスローされます。
`catch(Exception $e)`:
この構文は、基本的な`Exception`クラスの例外をキャッチします。
`Exception`クラスは、PHPの例外階層の基底クラスです。そのため、具体的な例外クラス(`PDOException`を含む)を指定せずに、全ての例外をキャッチする場合にこのクラスを使用することができます。
以下は、これらの違いを示す例です:
try {
// 何らかのPDO操作
} catch (PDOException $e) {
echo "PDO error: " . $e->getMessage();
} catch (Exception $e) {
echo "General error: " . $e->getMessage();
}
このコードでは、まず`PDOException`がキャッチされ、それに関連するエラーメッセージが出力されます。もし`PDOException`以外のタイプの例外がスローされた場合、次の`catch`ブロックが実行され、一般的なエラーメッセージが出力されます。
一般的には、より具体的な例外タイプから順に`catch`ブロックを定義し、最後に最も汎用的な例外タイプ(この場合は`Exception`)をキャッチするようにします。これにより、異なるタイプの例外に対して異なる処理を行うことができます。
【メモ】
「スロー」という言葉は、プログラミングの文脈では「例外を発生させる」という意味で使用されます。しかし、その言葉自体は「投げる」や「発射する」という意味です。プログラミングにおける「スロー」は、特定のエラーコンディションや予期しない状況が発生したときに、例外オブジェクトを「投げる」アクションを指します。
例外が「スロー」されると、プログラムの通常の実行フローは中断され、関連するcatchブロックまたは例外ハンドラーが見つかるまでコードの呼び出しスタックが遡られます。もし該当するcatchブロックやハンドラーが見つからない場合、多くのプログラムはエラーメッセージを表示して終了します。
したがって、「スロー」は例外を発生させるアクションを指し、それによってプログラムの通常の実行が中断されることを意味します。これは「働く」という意味とは異なります。
Q. Error クラスは Exception を継承していないので、 キャッチし損ねた例外を catch (Exception $e) { ... } ブロックで受け止めているような PHP 5 のコードでは、 Error をキャッチできません。 catch (Error $e) { ... } ブロックを用意するか、あるいは set_exception_handler() でハンドラを設定する必要があります。とは。
A. この説明は、PHP 7で導入された新しいエラーハンドリングの概念に関するものです。以前のバージョンとの互換性や新しいエラーハンドリングの概念を理解するために、この情報が提供されています。わかりやすく説明すると:
PHP 7の変更点:
PHP 7では、致命的なエラーや回復不能なエラー(例: メモリの不足)を表す新しい`Error`クラスが導入されました。
これは、それまでの`Exception`クラスとは異なるものです。
`Error`クラスと`Exception`クラスの関係:
重要な点は、`Error`クラスは`Exception`クラスを継承していないということです。
これは、PHP 5のコードで`catch (Exception $e) { ... }`を使用している場合、PHP 7で導入された`Error`クラスのインスタンスをキャッチできないということを意味します。
対応策:
新しい`Error`クラスのインスタンスをキャッチするためには、`catch (Error $e) { ... }`ブロックを追加するか、`set_exception_handler()`関数を使用して全体的な例外ハンドラを設定する必要があります。
簡単に言えば、PHP 7は新しい`Error`クラスを導入しましたが、それは従来の`Exception`クラスとは異なるため、双方を適切にキャッチするための対応が必要です。
だからといっていままででは、catch (Exception $e)を使っていたが、今後は catch (Exception $e)ではなくcatch (Error $e) { ... } とか書き換える必要があるわけではない。混乱した3つの使い方についてしっかり理解する必要はある!
try {
// 何らかのコード...
} catch (PDOException $e) {
// PDO関連の例外を処理
} catch (Exception $e) {
// その他のランタイムエラーを処理
} catch (Error $e) {
// システムレベルや致命的なエラーを処理
}