it-swarm.com.de

Ausnahme / Fehler bei Datenbanktransaktion wird abgefangen

Ich benutze die folgende Methode in Joomla 2.5 und 3, um eine Datenbankabfrage auszuführen -

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

aber wie kann ich Fehler/Ausnahmen abfangen, wenn die Abfrage aus irgendeinem Grund fehlschlägt, da $database->getErrorNum() veraltet ist?

11
dev-m

JError wurde in J3.x zugunsten von PHP Ausnahmen, da es 2 verschiedene Programmierkonzepte vermischt hat : Protokollierung und Fehlerbehandlung (die Protokollierungsseite wurde jetzt als JLog implementiert).

Für Ihren genauen Fall können Sie Ihren Code in einen try/catch-Block einschließen, um den Fehler zu erhalten, wie in this SO answer :

try {
    ...
    $db->setQuery($query);
    $result = $db->loadResult();
}
catch (Exception $e){
    echo $e->getMessage();
}

Beachten Sie, dass $database->execute() mit NICHT in J2.5 funktioniert. Sie sollten $database->query() verwenden, wenn Sie ein Äquivalent benötigen.

In Joomla 2.5 und 3.x auch die JDatabase ObjektmethodenupdateRecord() und insertRecord() Wirf Fehler, die du fangen kannst, wenn sie fehlschlagen:

try {
    JFactory::getDbo()->updateObject('#_table_name', $data);
} catch (Exception $e) {
    //...handle the exception
}

Wenn Sie nur für Joomla 3.x entwickeln, können Sie auch einen try catch-Block mit SQL-Transaktionen verwenden, um die Fehlerdetails abzurufen:

$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);
}
13
codinghands

Installieren Sie im Idealfall pecl, erweitern Sie dann die entsprechende JDatabase * -Klasse und überschreiben Sie JFactory :: getDbo () mit der folgenden Implementierung, um zu vermeiden, dass Millionen Code-Updates erforderlich sind, um jede kritische Datenbankabfrage in try catch-Anweisungen zu packen.

Das nächstbeste für mich ist die folgende Unterstützung für den alten und den neuen Weg:

Fügen Sie dies irgendwo ein

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

Dann benutze es so

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;
}
0
ekerner