ZendFramework1でMySQLのエラーコードを取得
ZendFramework1でMySQL等のDBを利用する場合、エラーコードを判別して処理をしたい場合があります。
try { $db->insert("db_table", $bind); echo "(登録完了)"; } catch (Zend_Exception $e) { echo $e->getCode(); echo $e->getMessage(); }
普通は、こんな感じですね。
ただし、困ったことにここで取れるエラーコードは「23000」など、大まかなエラーコードで
いろいろなエラーで結構重複しています。
https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
厳密には上記のMySQLエラーコード表にあるSQLSTATEが返ってきます。
そちらではなく、Errorコードの方が欲しい場合にどうするかです。
getMessage()で取れるStringをパースしてもいいのですが、面倒ですし不確実です。
Zend_Exception $e の中身をZend_Debug::dump($e)で覗いてみるとこんな感じです。
object(Zend_Db_Statement_Exception)#87 (8) { ["_previous":"Zend_Exception":private] => NULL ["message":protected] => string(111) "SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '123456739' for key 'uniq_key'" ["string":"Exception":private] => string(0) "" ["code":protected] => int(23000) ["file":protected] => string(69) "/usr/local/zend/share/ZendFramework/library/Zend/Db/Statement/Pdo.php" ["line":protected] => int(234) ["trace":"Exception":private] => array(12) { (途中略) ["previous":"Exception":private] => NULL ["errorInfo"] => array(3) { [0] => string(5) "23000" [1] => int(1062) [2] => string(57) "Duplicate entry '123456789' for key 'uniq_key'" } } }
ちゃんと、最後のerrorInfoで欲しいエラーコード「1062」が入っていることが判ります。
しかし、これを取得する関数はありません。どうすれば・・・ということで試行錯誤してみた結果、
$e->getChainedException()->errorInfo[1] で取れます。
getChainedException()で、下位情報のPDOExceptionが取得でき、そこからerrorInfoを取得します。
Zend_Db_Statement_Exceptionからは直接取得できません。(たぶんprivateなので)
ですので、おそらくPDO(MySQL)に依存した方法です。他のDB等でどうなるかはしりません。
なぜこうなるのか・・・は抽象化した結果でしょうが、気にしないことにします。
正式な取得方法があるのかもしれませんが、MySQL以外使いませんし動けばいいのです!(ダメ思想)
修正したコードはこんな感じでしょうか。
try { $db->insert("db_table", $bind); echo "(登録完了)"; } catch (Zend_Exception $e) { if($e->getChainedException()->errorInfo[1] == 1062) { echo "(ERR:重複登録)"; } }