Veritabanı işleminde kural dışı durum / hata yakalama


11

Veritabanı sorgusu yürütmek için joomla 2.5 ve 3 aşağıdaki yolu kullanıyorum -

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

ancak sorgu $database->getErrorNum()kullanımdan kaldırıldığı gibi herhangi bir nedenle başarısız olursa hataları / istisnaları nasıl yakalarım ?

Yanıtlar:


13

JError, J3.x'te PHP istisnaları lehine, 2 farklı programlama kavramını karıştırdığı için günlüğe kaydedildi: günlüğe kaydetme ve hata işleme (günlüğe kaydetme tarafı şimdi JLog olarak uygulandı ).

Tam durumunuz için, bu SO yanıtında gösterildiği gibi, hatayı almak için kodunuzu bir dene / yakala bloğuna sarabilirsiniz :

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

Not $database->execute()belirtilmektedir J2.5 içinde DEĞİL çalışması . $database->query()Eşdeğeri gerekiyorsa kullanmalısınız .

Joomla 2.5 ve 3.x'te JDatabasenesne yöntemleri updateRecord() ve insertRecord()ayrıca başarısız olursa yakalayabileceğiniz hatalar atar:

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

Yalnızca Joomla 3.x için geliştiriyorsanız , hata ayrıntılarını almak için SQL işlemleriyle bir try catch bloğunu da kullanabilirsiniz :

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

benim joomla 2.5.11 $ veritabanı-> execute (); joomla 2.5 ve 3 için tek bileşen yaptığım gibi iyi çalışıyor. Ancak execute () ile ilk try-catch bloğunuz 2.5.11'de çalışmıyor. Dediğin gibi Jdatabase nesne yöntemleri sadece 2.5 ve 3.1 çalışır, bu yüzden bunu kullanmayacaksınız. Peki bunu uygulamak için kullanılabilir diğer yöntemler ve hem J 2.5 ve 3 sürümleri ile uyumlu ??.
dev-m

Ha, garip, dokümanlar -> execute () 'in 2.5'te çalışmadığını söylüyorlar. Düzenleyecek. JDatabase nesnesi yöntemleri tüm J3.X sürümlerinde çalışmalıdır
kodlama el

1
"Ama execute () ile ilk try-catch bloğunuz 2.5.11'de çalışmıyor" ... eğer varsa hangi hatayı alıyorsunuz?
kodlama el

Mesajı kontrol etmedim ama bir dönüş yanlış koymak; orada ama kesinlikle yanlış döndürmüyor, bu yüzden kontrol 2.5.11 sitemde catch bloğuna girmiyor.
dev-m

Genel Yapılandırma'da hata raporlamayı etkinleştirebilir misiniz? PHP'nin hata üretip üretmediğini görmek için.
codinghands

0

İdeal olarak pecl'i yükleyin, ardından uygun JDatabase * sınıfını genişletin ve JACTtory :: getDbo () yöntemini, aşağıdaki catch uygulamasıyla, try catch deyimlerinde her kritik db sorgusunu sarmak için bir squillion kod güncellemesi ihtiyacını ortadan kaldırmak için geçersiz kılın.

Benim için en iyi şey, eski ve yeni yol için aşağıdaki destek:

Bunu bir yere dahil et

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

O zaman böyle kullan

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.