it-swarm-eu.dev

Eccezione / errore di acquisizione nella transazione del database

Sto usando il seguente modo in joomla 2.5 e 3 per eseguire query di database -

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

ma come posso rilevare errori/eccezioni se la query fallisce per qualsiasi motivo poiché $database->getErrorNum() è obsoleto?

11
dev-m

JError è stato deprecato in J3.x, a favore di PHP, in quanto mescolati 2 diversi concetti di programmazione : registrazione e gestione degli errori (il lato di registrazione è stato ora implementato come JLog ).

Per il tuo caso esatto, puoi racchiudere il codice in un blocco try/catch per ottenere l'errore, come mostrato in this SO answer :

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

Si noti che $database->execute() è indicato come NON funziona in J2.5 . Dovresti usare $database->query() se hai bisogno di un equivalente.

In Joomla 2.5 e 3.x anche JDatabase object objectupdateRecord() e insertRecord() generano anche errori che puoi rilevare se falliscono:

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

Se stai sviluppando solo per Joomla 3.x, puoi anche utilizzare un blocco catch catch con Transazioni SQL per ottenere i dettagli dell'errore:

$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

Idealmente installare pecl quindi estendere la classe JDatabase * appropriata e sovrascrivere JFactory :: getDbo () con un'implementazione di seguito per eliminare la necessità di un aggiornamento del codice squillion per avvolgere ogni query db critica nelle istruzioni catch catch.

La prossima cosa migliore per me è il supporto di seguito per il vecchio e il nuovo modo:

Includilo da qualche parte

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

Quindi usalo in questo modo

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