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
文)について考えてみましょう。スローされた PDOException
は try - 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
実行結果からスローされた PDOException
を catch
ブロックで処理できているのがわかります。
catch
ブロックの後の処理(echo "end" . PHP_EOL;
)もそのまま継続して実行される点も確認しておきましょう。スローされた例外をcatch
ブロックで処理して、そこで処理を終了するのではありません。catch
ブロック以降の処理はそのまま実行されるようになっています。
まとめ
- 例外はエラーと異なり、例外発生時の処理を実装できる
- 例外処理は
try - catch
文によって実装する try
ブロックで発生した例外をcatch
ブロックで捕捉できる