PDO の errorInfo でエラー内容を確認する
PDO でエラーが起きたとき、何が原因かを特定するには errorInfo メソッドが役に立つ。errorInfo は PDO オブジェクトと PDOStatement オブジェクトの両方に用意されており、直近のエラー情報を配列で返す。
errorInfo の戻り値
errorInfo は 3 要素の配列を返す。
| インデックス | 内容 | 例 |
|---|---|---|
| 0 | SQLSTATE コード | 42S02 |
| 1 | ドライバ固有エラーコード | 1146 |
| 2 | ドライバ固有メッセージ | Table 'mydb.users' doesn't exist |
インデックス 0 の SQLSTATE コードは ISO/ANSI SQL の標準規格で定められたもので、データベースの種類を問わず共通のコードが返る。一方、インデックス 1 と 2 はドライバ(MySQL、PostgreSQL など)固有の情報になる。
PDO オブジェクトの errorInfo
PDO オブジェクトの errorInfo は、prepare や exec など PDO 自体のメソッドで発生したエラーを返す。
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
$result = $pdo->exec( 'DROP TABLE nonexistent_table' );
if ( $result === false )
{
$error = $pdo->errorInfo();
echo $error[0]; // SQLSTATE コード
echo $error[1]; // ドライバエラーコード
echo $error[2]; // エラーメッセージ
}ERRMODE_SILENT の場合はエラーが自動で報告されないため、戻り値を確認してから errorInfo を呼ぶ流れになる。
PDOStatement の errorInfo
PDOStatement の errorInfo は、execute や fetch など、ステートメント単位で発生したエラーを返す。
$stmt = $pdo->prepare( 'SELECT * FROM nonexistent_table' );
$stmt->execute();
$error = $stmt->errorInfo();
if ( $error[0] !== '00000' )
{
echo 'SQLSTATE: ' . $error[0];
echo 'コード: ' . $error[1];
echo 'メッセージ: ' . $error[2];
}SQLSTATE コード「00000」はエラーなしを意味する。この値でないなら何らかの問題が発生している。
errorCode との違い
PDO には errorInfo のほかに errorCode メソッドもある。
SQLSTATE コードだけを文字列で返す。エラーの有無を手早く判定したいときに使う。
SQLSTATE コード、ドライバ固有のコード、メッセージの 3 要素を配列で返す。原因の特定にはこちらが必要になる。
errorCode は errorInfo のインデックス 0 と同じ値を返すだけなので、詳しい原因を知りたければ errorInfo を使うほうがよい。
ERRMODE_EXCEPTION との使い分け
ERRMODE_EXCEPTION を設定している場合、エラーは PDOException として自動的にスローされるため、errorInfo を明示的に呼ぶ場面は少なくなる。PDOException の getMessage() にエラーメッセージが含まれるからだ。
try
{
$stmt = $pdo->prepare( 'SELECT * FROM nonexistent_table' );
$stmt->execute();
}
catch ( PDOException $e )
{
// getMessage() で十分な情報が得られる
echo $e->getMessage();
// より詳しく知りたい場合は errorInfo も使える
$error = $stmt->errorInfo();
echo 'ドライバコード: ' . $error[1];
}実務では ERRMODE_EXCEPTION を基本にしつつ、ドライバ固有のエラーコードで処理を分岐させたいときだけ errorInfo を併用する、という使い方が現実的だろう。
よく見る SQLSTATE コード
代表的な SQLSTATE コードを知っておくと、エラーの切り分けが速くなる。
| SQLSTATE | 意味 |
|---|---|
| 00000 | エラーなし |
| 23000 | 一意制約違反(重複) |
| 42S02 | テーブルが存在しない |
| 42000 | SQL 構文エラー |
たとえば 23000 が返ってきたら、UNIQUE 制約やプライマリキーの重複が原因だとすぐにわかる。errorInfo と組み合わせれば、エラーの種類に応じたハンドリングが可能になる。