การจับข้อยกเว้น / ข้อผิดพลาดในการทำธุรกรรมฐานข้อมูล


11

ฉันใช้วิธีต่อไปนี้ใน joomla 2.5 และ 3 เพื่อรันการสืบค้นฐานข้อมูล -

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

แต่ฉันจะจับข้อผิดพลาด / ข้อยกเว้นได้อย่างไรหากแบบสอบถามล้มเหลวด้วยเหตุผลใดก็ตามที่$database->getErrorNum()เลิกใช้แล้ว

คำตอบ:


13

JError ได้รับการคัดค้านใน J3.x ในความโปรดปรานของข้อยกเว้น PHP, ในขณะที่มันรก 2 แนวคิดการเขียนโปรแกรมที่แตกต่างกัน : เข้าสู่ระบบและจัดการข้อผิดพลาด (ด้านการเข้าสู่ระบบในขณะนี้ได้รับการดำเนินการเป็นJLog )

สำหรับกรณีที่แน่นอนของคุณคุณสามารถใส่โค้ดใน try / catch block เพื่อรับข้อผิดพลาดดังแสดงในคำตอบ SO นี้ :

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

ทราบว่า$database->execute()มีการระบุไว้ในการทำงานไม่ได้อยู่ใน J2.5 คุณควรใช้$database->query()ถ้าคุณต้องการที่เทียบเท่า

ใน Joomla 2.5 และ 3.x JDatabaseวิธีการของวัตถุ updateRecord()และinsertRecord()ยังโยนข้อผิดพลาดที่คุณสามารถตรวจพบได้หากล้มเหลว:

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

หากคุณกำลังพัฒนาสำหรับ Joomla 3.x เท่านั้นคุณสามารถใช้ catch catch block กับธุรกรรม SQLเพื่อรับรายละเอียดข้อผิดพลาด:

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

ใน joomla ของฉัน 2.5.11 $ database-> execute (); ทำงานได้ดีเพราะฉันกำลังสร้างส่วนประกอบเดียวสำหรับ joomla 2.5 และ 3 แต่บล็อก try-catch แรกของคุณที่มี execute () ไม่ทำงานใน 2.5.11 อย่างที่คุณบอกว่าวิธีการของวัตถุ Jdatabase นั้นใช้งานได้เพียง 2.5 และ 3.1 ดังนั้นอย่าใช้มันดังนั้นวิธีการอื่น ๆ ที่มีให้ใช้ในการทำสิ่งนี้และเข้ากันได้กับทั้ง J 2.5 และ 3 รุ่น ??
dev-m

ดูเหมือนว่าเอกสารจะระบุว่า -> execute () ไม่ทำงานใน 2.5 จะแก้ไข วิธีการ JDatabase วัตถุควรทำงานในทุกรุ่น
J3.X

1
"แต่บล็อก try-catch แรกของคุณที่มี execute () ไม่ทำงานใน 2.5.11" ... คุณมีข้อผิดพลาดอะไรบ้างถ้ามี?
เข้ารหัสรหัส

ฉันไม่ได้ตรวจสอบข้อความ แต่ฉันใส่กลับเท็จ มี แต่มันจะไม่ส่งคืนเท็จอย่างแน่นอนดังนั้นการควบคุมจะไม่เข้าบล็อก catch ในไซต์ 2.5.11 ของฉัน
dev-m

คุณสามารถเปิดใช้งานการรายงานข้อผิดพลาดในการกำหนดค่าส่วนกลางเพื่อดูว่า PHP กำลังสร้างข้อผิดพลาดหรือไม่
เข้ารหัสรหัส

0

การติดตั้ง pecl จะเป็นการดีเลิศจากนั้นขยายคลาส JDatabase * และแทนที่ JFactory :: getDbo () ที่เหมาะสมด้วยการใช้งานด้านล่างเพื่อกำจัดความต้องการการอัพเดตโค้ดที่ซับซ้อนเพื่อตัดคำสืบค้น db ที่สำคัญทั้งหมดในคำสั่ง catch catch

สิ่งที่ดีที่สุดถัดไปสำหรับฉันคือการสนับสนุนด้านล่างสำหรับวิธีเก่าและวิธีใหม่:

รวมสิ่งนี้ไว้ที่ไหนสักแห่ง

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

จากนั้นใช้มันเช่นนี้

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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.