PDO が提供するエラー処理方法は 3 通り存在し、 アプリケーションの開発形態によって使い分けることができます。
PDO::ERRMODE_SILENT
PHP 8.0.0 より前のバージョンでは、これがデフォルトのモードでした。 ステートメントおよびデータベースオブジェクトの エラーについて、PDO は単にそのエラーコードのみを設定します。 これを取得するには PDO::errorCode() および PDO::errorInfo() メソッドを使用します。 ステートメントオブジェクトへのコールによってエラーが発生した場合は、 そのオブジェクトの PDOStatement::errorCode() あるいは PDOStatement::errorInfo() メソッドを呼び出します。 データベースオブジェクトへのコールによってエラーが発生した場合は、 その代わりにデータベースオブジェクト上の同じメソッドを呼び出します。
PDO::ERRMODE_WARNING
エラーコードを設定することに加え、PDO は 伝統的な E_WARNING メッセージも出力します。この設定はデバッグ/テストの際に有用で、 アプリケーションの動作を妨げることなしに問題点を確認できるように なります。
PDO::ERRMODE_EXCEPTION
PHP 8.0.0 以降では、これがデフォルトのモードです。 エラーコードを設定することに加え、PDO は PDOException をスローします。エラーコードや 関連情報が、クラスのプロパティとして設定されます。 この設定もまたデバッグ時に有用で、エラーが発生した時点で スクリプトの実行を停止させることによりコード内の問題点を 見つけやすくなります (例外によりスクリプトが終了した際には、トランザクションは自動的に ロールバックされることを覚えておきましょう)。
このモードが有用である理由のひとつとして、伝統的な PHP 形式の警告よりも より明確にエラー処理コードが書けることがあります。例外を発生させず、 データベースへのコールのたびに毎回明示的に戻り値をチェックすることに 比べると、コードの量やネストを減らすことができます。
PHP の例外についての詳細な情報は、 例外 を参照ください。
PDO のエラーコードは、SQL-92 の SQLSTATE エラーコード文字列に 標準化されています。 ネイティブのコードを適切な SQLSTATE コードに変換するのは、個々の PDO ドライバの仕事となります。 PDO::errorCode() メソッドは SQLSTATE コードを返します。 エラーについての詳細な銃尾法が知りたい場合、PDO では PDO::errorInfo() メソッドも提供しており、 これは SQLSTATE コード、ドライバ固有のエラーコードおよびドライバ固有の エラーメッセージを含む配列を返します。
例1 PDO インスタンスの作成およびエラーモードの設定
<?php
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
try {
$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
?>
注意:
PDO::__construct() は、接続に失敗した場合は常に PDOException をスローします。 これは、現在設定されている
PDO::ATTR_ERRMODE
が何であっても同じです。例外を処理しないと、fatal エラーとなります。
例2 PDO インスタンスの作成およびコンストラクタでのエラーモードの設定
<?php
$dsn = 'mysql:dbname=test;host=127.0.0.1';
$user = 'googleguy';
$password = 'googleguy';
/*
ERRMODE を WARNING にした場合でも、コンストラクタを try/catch で囲むのは有効です。
接続に失敗した場合、ERRMODE が何であろうが PDO::__construct が PDOException をスローするからです。
*/
try {
$dbh = new PDO($dsn, $user, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
exit;
}
// このテーブルが存在しないとして、このコードを実行すると E_WARNING レベルのエラーになります。例外にはなりません。
$dbh->query("SELECT wrongcolumn FROM wrongtable");
?>
上の例の出力は以下となります。
Warning: PDO::query(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.wrongtable' doesn't exist in /tmp/pdo_test.php on line 18