在数据库事务中捕获异常/错误


11

我在joomla 2.5和3中使用以下方式执行数据库查询-

$database = JFactory::getDBO();
$database->setQuery
$database->execute();

但是,如果由于任何原因而导致查询失败,我该如何捕获错误/异常$database->getErrorNum()

Answers:


13

JError在J3.x中已弃用,支持PHP异常,因为它混合了两种不同的编程概念:日志记录和错误处理(日志记录端现已实现为JLog)。

对于您的确切情况,您可以将代码包装在try / catch块中以获取错误,如此SO答案所示:

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);
}

在我的joomla 2.5.11 $ database-> execute();中 可以正常工作,因为我正在为joomla 2.5和3制作单个组件。但是,第一个带有execute()的try-catch块在2.5.11中不起作用。正如您所说的,Jdatabase对象方法仅适用于2.5和3.1,因此无法使用它。那么还有什么其他方法可以实现此功能并与J 2.5和3版本兼容?
dev-m

嗯,很奇怪,文档似乎指出-> execute()在2.5中不起作用。将进行编辑。JDatabase对象方法应可在所有J3.X版本中使用
编码手册

1
“但是您的第一个带有execute()的try-catch块在2.5.11中不起作用”。。。
codinghands

我没有检查消息,但返回false。在那里,但是它肯定不会返回false,所以控件也不会进入我的2.5.11站点的catch块中。
dev-m

您可以在全局配置中启用错误报告以查看PHP是否生成任何错误。
codinghands

0

理想情况下,安装pecl,然后扩展适当的JDatabase *类,并使用以下实现覆盖JFactory :: getDbo(),从而无需进行大量代码更新即可将每个关键数据库查询包装在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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.