it-swarm-id.com

Menangkap pengecualian / kesalahan dalam transaksi basis data

Saya menggunakan cara berikut di joomla 2.5 dan 3 untuk mengeksekusi query database -

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

tetapi bagaimana cara menangkap kesalahan/pengecualian jika kueri gagal karena alasan apa pun karena $database->getErrorNum() sudah usang?

11
dev-m

JError telah ditinggalkan dalam J3.x, mendukung PHP pengecualian, seperti itu dicampur 2 konsep pemrograman yang berbeda : logging dan penanganan kesalahan (sisi logging sekarang telah diimplementasikan sebagai JLog ).

Untuk kasus yang tepat, Anda dapat membungkus kode Anda dalam blok coba/tangkap untuk mendapatkan kesalahan, seperti yang ditunjukkan pada this SO jawaban :

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

Perhatikan bahwa $database->execute() dinyatakan ke TIDAK bekerja di J2.5 . Anda harus menggunakan $database->query() jika Anda membutuhkan yang setara.

Di Joomla 2.5 dan 3.x the JDatabase metode objekupdateRecord() dan insertRecord() juga melempar kesalahan yang dapat Anda tangkap jika gagal:

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

Jika Anda hanya mengembangkan untuk Joomla 3.x, Anda juga dapat menggunakan blok coba tangkap dengan transaksi SQL untuk mendapatkan detail kesalahan:

$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

Idealnya instal pecl kemudian perpanjang kelas JDatabase * yang sesuai dan ganti JFactory :: getDbo () dengan implementasi di bawah ini untuk menghilangkan kebutuhan akan pembaruan kode triliunan untuk membungkus setiap kueri db penting dalam pernyataan coba tangkap.

Hal terbaik berikutnya bagi saya adalah dukungan di bawah ini untuk cara lama dan cara baru:

Sertakan ini di suatu tempat

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

Kemudian gunakan seperti ini

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