0Pricing
PHP Academy · レッスン

Try、Catch、Finally

try/catch/finallyブロックを使って実行時例外を適切に処理します

「Try、Catch、Finally」はCoddyKit上の無料PHP Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPHP Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 PHP Academyコースには全4レッスンが含まれています。

例外とエラー

PHP には、問題を通知する方法が2つあります。

  • Errors — 従来の PHP の Notice、Warning、Fatal です(前のレッスンで説明しました)
  • Exceptions — 特別な事態が発生したときにスローされるオブジェクトで、try/catch で捕捉します

例外は、回復可能なエラーを処理するための、現代的で推奨される方法です。

例外をスローする

throw を使って、問題が発生したことを通知します。

<?php
function divide(float $a, float $b): float {
    if ($b == 0) {
        throw new InvalidArgumentException('Cannot divide by zero');
    }
    return $a / $b;
}

echo divide(10, 2);   // 5
// divide(10, 0);     // throws exception

try / catch ブロック

例外をスローする可能性のあるコードを try で囲み、catch で例外を処理します。

<?php
try {
    $result = divide(10, 0);
    echo $result;
} catch (InvalidArgumentException $e) {
    echo 'Error: ' . $e->getMessage();
    echo ' in ' . $e->getFile() . ':' . $e->getLine();
}

複数の catch ブロック

異なる例外タイプは、それぞれ別の catch ブロックで捕捉します。

<?php
try {
    $pdo = new PDO($dsn, $user, $pass);
    $result = performQuery($pdo);
} catch (PDOException $e) {
    error_log('DB error: ' . $e->getMessage());
    echo 'Database unavailable';
} catch (RuntimeException $e) {
    echo 'Runtime error: ' . $e->getMessage();
} catch (\Throwable $e) {
    echo 'Unexpected error: ' . $e->getMessage();
}

finally ブロック

例外がスローされたかどうかに関係なく、finally は実行されます。後片付けに最適です。

<?php
$connection = null;
try {
    $connection = openDatabaseConnection();
    $data = fetchData($connection);
} catch (DatabaseException $e) {
    error_log($e->getMessage());
    echo 'DB error';
} finally {
    // Always runs — even if exception was thrown
    if ($connection) {
        closeConnection($connection);
    }
}

例外のクラス階層

PHP の例外クラス階層:

  • Throwable(インターフェース)
  • ├─ Error — PHP エンジンのエラー(TypeError、ParseError など)
  • └─ Exception — アプリケーションの例外
  • ├─ RuntimeException
  • ├─ InvalidArgumentException
  • ├─ LogicException
  • └─ PDOException

Throwable を捕捉する

Throwable を使って、Exception と PHP の Error の両方を捕捉します。

<?php
try {
    $result = someFunction();
} catch (\Exception $e) {
    echo 'Exception: ' . $e->getMessage();
} catch (\Error $e) {
    echo 'PHP Error: ' . $e->getMessage();
}

// Or catch both at once:
try {
    // ...
} catch (\Throwable $e) {
    echo get_class($e) . ': ' . $e->getMessage();
}

ユニオン catch(PHP 8)

PHP 8 では、1つの catch ブロックで複数の例外タイプを捕捉できます。

<?php
try {
    processRequest();
} catch (InvalidArgumentException | RuntimeException $e) {
    echo 'Handled: ' . $e->getMessage();
}

// Compare PHP 7 approach:
// catch (InvalidArgumentException $e) { ... }
// catch (RuntimeException $e) { ... }

例外を再スローする

例外を捕捉して記録した後、コールスタックを上へ伝播させるために再スローします。

<?php
function processOrder(int $id): void {
    try {
        $order = loadOrder($id);
        $order->process();
    } catch (PaymentException $e) {
        error_log('Payment failed for order ' . $id . ': ' . $e->getMessage());
        throw $e;  // re-throw after logging
    }
}

例外のチェーン

コンテキストを保持するため、元の例外を「previous」として渡します。

<?php
try {
    $data = fetchFromAPI();
} catch (NetworkException $e) {
    throw new ServiceUnavailableException(
        'Cannot reach upstream service',
        0,
        $e  // $previous — preserves original cause
    );
}

// Retrieve original:
// $e->getPrevious()

set_exception_handler

グローバルな未捕捉例外ハンドラーを登録します。

<?php
set_exception_handler(function(\Throwable $e): void {
    error_log(sprintf(
        '[UNCAUGHT] %s: %s in %s:%d',
        get_class($e),
        $e->getMessage(),
        $e->getFile(),
        $e->getLine()
    ));
    http_response_code(500);
    echo 'An unexpected error occurred. Please try again.';
    exit(1);
});

理解度チェック

try/catch/finally のうち、例外がスローされたかどうかに関係なく必ず実行されるブロックはどれですか。

まとめ:try/catch/finally

例外処理のまとめ:

  • throw new ExceptionClass() で例外をスローします
  • catch (Type $e) で捕捉します
  • タイプごとに複数の catch ブロックを使用します
  • finally は常に実行されるため、後片付けに使用します
  • PHP 8 のユニオン catch:catch (A | B $e)
  • 再スローしてコールスタックのコンテキストを保持します

よくある質問

「Try、Catch、Finally」レッスンは無料ですか?

はい。「Try、Catch、Finally」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、PHP Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 PHP Academyコースには全4レッスンが含まれています。

「Try、Catch、Finally」で何を学びますか?

try/catch/finallyブロックを使って実行時例外を適切に処理します ブラウザで直接実行するハンズオンコードでPHP Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

PHP Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPHP Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「Try、Catch、Finally」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPHP Academyレッスンでコードを書いて実行できますか?

はい。すべてのPHP Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. PHPのエラーの種類と報告
  2. Try、Catch、Finally
  3. カスタム例外の作成
  4. エラーのログ記録とベストプラクティス
← PHP Academyに戻る