Eccezione / errore di acquisizione nella transazione del database


11

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()è obsoleta?

Risposte:


13

JError è stato deprecato in J3.x, a favore delle eccezioni di PHP, in quanto ha mescolato 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 questa risposta SO :

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

Si noti che $database->execute()è riportata al lavoro non in J2.5 . Dovresti usare $database->query()se hai bisogno di un equivalente.

In Joomla 2.5 e 3.x i JDatabasemetodi oggetto updateRecord() e insertRecord()lanciano 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);
}

nel mio joomla 2.5.11 $ database-> execute (); funziona bene mentre sto realizzando un singolo componente per joomla 2.5 e 3. Ma il tuo primo blocco try-catch con execute () non funziona in 2.5.11. Come hai detto, i metodi oggetto Jdatabase funzionano solo con 2.5 e 3.1, quindi non usarli, quindi quali altri metodi disponibili per implementarlo e compatibili con entrambe le versioni J 2.5 e 3 ??.
dev-m,

Eh, strano, i documenti sembrano affermare che -> execute () non funziona in 2.5. Modifica. I metodi degli oggetti JDatabase dovrebbero funzionare in tutte le versioni di
J3.X

1
"Ma il tuo primo blocco try-catch con execute () non funziona in 2.5.11" ... quale errore viene visualizzato, se presente?
codinghands

Non ho controllato il messaggio ma ho inserito un reso falso; ma non sta tornando falso di sicuro, quindi il controllo non entra nel blocco catch nel mio sito 2.5.11.
dev-m,

Potresti abilitare la segnalazione degli errori in Configurazione globale Per vedere se PHP sta generando errori.
codinghands

0

Idealmente installare pecl quindi estendere la classe JDatabase * appropriata e sovrascrivere JFactory :: getDbo () con un'implementazione di seguito per eliminare la necessità di un squilione di aggiornamenti di codice 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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.