PHP-DB - 11. 例外処理

これまでに PDOException をスローする方法を学習しました。以下のように PDO クラスの setAttribute メソッドを使って、 PDO::ATTR_ERRMODE 属性に PDO::ERRMODE_EXCEPTION を指定することで、異常時に PDOException をスローするように変更できます。

$pdo = new PDO($dsn, $username, $passwd);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

次に例外処理( try - catch 文)について考えてみましょう。スローされた PDOExceptiontry - catch 文を使って以下のように処理できます。次のプログラム( pdo9.php )を作成してみましょう。

<?php
try {
    $dsn = "mysql:host=localhost;dbname=eldb;charset=utf8mb4";
    $username = "root";
    $password = "admin";
    $pdo = new PDO($dsn, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Invalid SQL
    $sql = "select id, title from categorie";
    $st = $pdo->query($sql); // throw PDOException
    var_dump($st);

} catch (PDOException $e) {
    echo "catch" . PHP_EOL;
    echo $e->getCode() . PHP_EOL;
    echo $e->getMessage() . PHP_EOL;
}
echo "end" . PHP_EOL;

このプログラムでは try の処理ブロック {} の中で不正なSQLを定義して $pdo->query($sql) を呼び出しています。この場合 PDOException がスローされるので、処理は catch の処理ブロックに移ります。

} catch (PDOException $e) {
    echo "catch" . PHP_EOL;
    echo $e->getCode() . PHP_EOL;
    echo $e->getMessage() . PHP_EOL;
}

catch (PDOException $e) は、キャッチ対象の例外クラスを PDOException とし、スローされた例外インスタンスを $e 変数で受け取ることを意味します。また catch の処理ブロック {} においては echo 命令を使って、 $e->getCode() の戻り値(エラーコード)や、 $e->getMessage() の戻り値(エラーメッセージ)を出力しています。

実際に取得できるエラーコードやエラーメッセージは接続するデータベースによって異なります。

それでは実際にプログラムを実行してみましょう。

$ php pdo9.php
catch
HY000
SQLSTATE[HY000]: General error: 1 no such table: categorie
end

実行結果からスローされた PDOExceptioncatch ブロックで処理できているのがわかります。

catch ブロックの後の処理( echo "end" . PHP_EOL; )もそのまま継続して実行される点も確認しておきましょう。スローされた例外を catch ブロックで処理して、そこで処理を終了するのではありません。 catch ブロック以降の処理はそのまま実行されるようになっています。

まとめ

  • 例外はエラーと異なり、例外発生時の処理を実装できる
  • 例外処理は try - catch 文によって実装する
  • try ブロックで発生した例外を catch ブロックで捕捉できる