Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】UnexpectedValueException::getPrevious()メソッドの使い方

getPreviousメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

getPreviousメソッドは、現在の例外がスローされる原因となった、直前の例外を取得するために実行するメソッドです。PHPでは、ある処理で例外が発生した際に、その例外を捕捉(catch)し、より具体的な情報を持つ新しい例外をスローすることができます。このとき、元の例外情報を失わないように、新しい例外を生成するコンストラクタの第3引数に元の例外オブジェクトを渡すことで、例外を数珠つなぎにできます。この仕組みを「例外チェーン」と呼びます。getPreviousメソッドは、この連鎖された一つ前のThrowableオブジェクトを返します。これにより、多層的な処理のどこで根本的な問題が発生したのかを正確に追跡することが可能となり、デバッグ作業を効率化できます。もし連鎖している前の例外が存在しない場合、このメソッドはnullを返します。UnexpectedValueExceptionクラスはExceptionクラスを継承しているため、この便利なメソッドを利用できます。

構文(syntax)

1<?php
2
3try {
4    // 最初の例外を発生させる
5    try {
6        throw new InvalidArgumentException('無効な引数です。');
7    } catch (InvalidArgumentException $e) {
8        // 最初の例外をラップして、新しい例外をスローする
9        throw new UnexpectedValueException('予期しない値です。', 0, $e);
10    }
11} catch (UnexpectedValueException $e) {
12    // getPrevious() で、ラップされた元の例外を取得する
13    $previousException = $e->getPrevious();
14
15    if ($previousException) {
16        echo "現在の例外: " . $e->getMessage() . "\n";
17        echo "先行する例外: " . $previousException->getMessage() . "\n";
18    }
19}
20
21?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

?Throwable

このメソッドは、例外が発生する直前に発生した例外オブジェクトを返します。例外が発生していない場合は、nullを返します。

サンプルコード

PHP Exception getPrevious で例外チェーンを辿る

1<?php
2
3declare(strict_types=1);
4
5/**
6 * ユーザーIDを検証し、問題があれば例外をスローする関数
7 *
8 * @param mixed $userId
9 * @return void
10 * @throws InvalidArgumentException ユーザーIDが整数でない場合
11 */
12function validateUserId(mixed $userId): void
13{
14    if (!is_int($userId)) {
15        // 処理の前提条件を満たさない低レベルな例外
16        throw new InvalidArgumentException('ユーザーIDは整数である必要があります。');
17    }
18    // ここでIDを使った処理が続くと仮定...
19    echo "ユーザーID ({$userId}) の検証に成功しました。" . PHP_EOL;
20}
21
22/**
23 * ユーザーデータを処理し、例外チェーンを実演する関数
24 *
25 * @param array $data
26 * @return void
27 */
28function processUserData(array $data): void
29{
30    try {
31        // 低レベルな検証関数を呼び出す
32        validateUserId($data['id'] ?? null);
33    } catch (InvalidArgumentException $e) {
34        // 捕捉した例外($e)を原因として、より具体的な状況を示す新しい例外をスローする
35        // 第3引数に元の例外を渡すことで、例外チェーンが作成される
36        throw new UnexpectedValueException(
37            'ユーザーデータの処理中に予期しない値が検出されました。',
38            0,
39            $e
40        );
41    }
42}
43
44// --- メイン処理 ---
45try {
46    // 不正なデータで関数を呼び出す
47    processUserData(['id' => 'user_123']);
48} catch (UnexpectedValueException $e) {
49    // スローされた最上位の例外を捕捉
50    echo '--- 例外が発生しました ---' . PHP_EOL;
51    echo 'メッセージ: ' . $e->getMessage() . PHP_EOL;
52    echo '例外クラス: ' . get_class($e) . PHP_EOL;
53
54    // getPrevious() を使って、この例外の原因となった直前の例外を取得する
55    $previousException = $e->getPrevious();
56
57    // 直前の例外が存在するかチェック
58    if ($previousException !== null) {
59        echo PHP_EOL . '--- 原因となった元の例外情報 (getPrevious() で取得) ---' . PHP_EOL;
60        echo 'メッセージ: ' . $previousException->getMessage() . PHP_EOL;
61        echo '例外クラス: ' . get_class($previousException) . PHP_EOL;
62        echo 'ファイル: ' . $previousException->getFile() . ' (' . $previousException->getLine() . '行目)' . PHP_EOL;
63    }
64}
65

このサンプルコードは、ある例外が別の例外を引き起こした際に、その原因となった元の例外を取得するgetPrevious()メソッドの使い方を解説します。このような例外の連鎖は「例外チェーン」と呼ばれ、エラーの根本原因を追跡するのに役立ちます。

コード内のprocessUserData関数では、validateUserId関数で発生したInvalidArgumentExceptioncatchブロックで捕捉します。そして、その捕捉した例外を原因として、より具体的な状況を示すUnexpectedValueExceptionを新たにスローしています。このとき、UnexpectedValueExceptionのコンストラクタの第3引数に元の例外を渡すことで、例外チェーンが形成されます。

メイン処理では、最終的にスローされたUnexpectedValueExceptionを捕捉し、そのオブジェクトに対してgetPrevious()メソッドを呼び出しています。これにより、チェーンの元となったInvalidArgumentExceptionの情報を取得し、表示することができます。

getPrevious()メソッドは引数を取らず、戻り値は?Throwable型です。これは、原因となった例外オブジェクトが存在すればそれを返し、存在しない場合はnullを返すことを意味します。このメソッドを使うことで、表層的なエラーだけでなく、その背景にある根本的な問題を効率的に調査できます。

getPrevious()メソッドは、ある例外が別の例外によって引き起こされた場合に、その原因となった元の例外を取得するために使います。サンプルコードのように、catchした例外を新しい例外の第3引数に渡してthrowすることで「例外チェーン」が作成され、getPrevious()で元の例外を辿れます。この引数を渡し忘れると、getPrevious()nullを返すため注意が必要です。また、getPrevious()の戻り値は元の例外がなければnullになるため、利用する前には必ずnullチェックを行ってください。この機能は、詳細な技術的エラーを、より業務内容に即した分かりやすいエラーとして再スローしつつ、根本原因の情報を失わずに伝えるために利用されます。

関連コンテンツ