Joomla 2.5および3で次の方法を使用してデータベースクエリを実行しています-
_$database = JFactory::getDBO();
$database->setQuery
$database->execute();
_
しかし、$database->getErrorNum()
が廃止されたためにクエリが何らかの理由で失敗した場合、どのようにエラー/例外をキャッチしますか?
JErrorはJ3.xで非推奨になり、PHP例外、そのため 2つの異なるプログラミング概念が混在 :ロギングとエラー処理(ロギング側は、 JLog )として実装されます。
正確な例として、コードをtry/catchブロックでラップしてエラーを取得できます this SO answer :
_try {
...
$db->setQuery($query);
$result = $db->loadResult();
}
catch (Exception $e){
echo $e->getMessage();
}
_
$database->execute()
は J2.5では機能しない と記述されていることに注意してください。同等の機能が必要な場合は、$database->query()
を使用してください。
Joomla 2.5と3.xでは JDatabase
オブジェクトメソッドupdateRecord()
とinsertRecord()
は、エラーが発生した場合にキャッチできるエラーもスローします。
_try {
JFactory::getDbo()->updateObject('#_table_name', $data);
} catch (Exception $e) {
//...handle the exception
}
_
Joomla 3.xのみを対象に開発している場合は、 SQLトランザクション でtry catchブロックを使用して、エラーの詳細を取得することもできます。
_$db = JFactory::getDbo();
try {
$db->transactionStart();
$query = $db->getQuery(true);
$values = array($db->quote('TEST_CONSTANT'), $db->quote('Custom'), $db->quote('/path/to/translation.ini'));
$query->insert($db->quoteName('#__overrider'));
$query->columns($db->quoteName(array('constant', 'string', 'file')));
$query->values(implode(',',$values));
$db->setQuery($query);
$result = $db->execute();
$db->transactionCommit();
}
catch (Exception $e) {
// catch any database errors.
$db->transactionRollback();
JErrorPage::render($e);
}
_
理想的には、peclをインストールしてから適切なJDatabase *クラスを拡張し、以下の実装でJFactory :: getDbo()をオーバーライドして、重要なすべてのdbクエリをtry catchステートメントでラップするための膨大なコード更新の必要性を排除します。
私にとって次善の策は、以下の古い方法と新しい方法のサポートです。
これをどこかに含める
class jDbUtils
{
protected static $dbErrorMessage = '';
public static function stupidJ3CatchDatabaseExecute($db, $cmd, $report = false) {
self::$dbErrorMessage = '';
try {
$res = $db->$cmd();
// legacy db error support
if (method_exists($db, 'getErrorNum') && $db->getErrorNum())
throw new Exception($db->getErrorMsg());
return $res;
} catch(Exception $e) {
self::$dbErrorMessage = $e->getMessage();
if ($report)
self::reportIfDbError();
return false;
}
}
public static function reportIfDbError()
{
if (self::$dbErrorMessage) {
JFactory::getApplication()->enqueueMessage(self::$dbErrorMessage, 'error');
return true;
}
}
}
次に、このように使用します
function someDbInteraction(){
$db = JFactory::getDbo();
$db->setQuery('SELECT no_such_col FROM no_such_table LIMIT 1');
$res = jDbUtils::stupidJ3CatchDatabaseExecute($db, 'loadResult');
if (jDbUtils::reportIfDbError())
return false;
// do more processing
return $res;
}