如何扩展CodeIgniter数据库实用程序类

时间:2014-11-24 23:44:38

标签: php mysql codeigniter mysqli codeigniter-2

问题

当我更新我的CodeIgniter 2.2.0应用程序以使用mysqli数据库驱动程序时,它破坏了CodeIgniter的backup function of the Database Utility Class。我以前成功获得数据库备份的地方,我现在收到错误......

  

您正在使用的数据库平台不支持的功能。

错误只是意味着Database Utility Class中的CodeIgniter备份功能不支持mysqli。根据在线文档,只支持MySQL。

但是,我不想使用已弃用的mysql数据库驱动程序。


可能的解决方法(不允许)

我想我可以通过简单地扩展CodeIgniter的数据库实用程序类来解决这个问题。但是,CodeIgniter does not allow this as per documentation ...

  

注意:数据库类不能扩展或替换为您自己的类。


另一种解决方法(致命错误)

编辑:my answerthe accepted answer基于此解决方法。

此GitHub页面描述了一种通过创建MY_Loader类来扩展核心来扩展数据库类的方法。

https://github.com/bcit-ci/CodeIgniter/wiki/Extending-Database-Drivers

然而,当我尝试这个解决方案时,我得到了这个致命错误......

  

文件名:core / MY_Loader.php,行号:49

     

致命错误:在第217行的/home/account/codeigniter/system/libraries/Session.php中调用未定义的方法CI_DB_mysqli_driver :: where()

第49行是:$db =& new $my_driver(get_object_vars($db));

我完全按照上面链接中所述使用MY_LoaderMY_DB_mysqli_utility看起来像这样......

<?php class MY_DB_mysqli_utility extends CI_DB_mysqli_utility {

    function __construct($params){
        parent::__construct($params);
        log_message('debug', 'Extended DB driver class instantiated!');
    }

    function _backup($params = array())
    {
        // the working backup function is here
        .....
    }

}

我不完全确定这个GitHub解决方法是否失败,因为它已经过时,我忽略了某些东西,或者是否因为我试图在CI_DB_mysqli_utility上使用它而不是CI_DB_mysqli_driver

编辑 :此解决方法失败,因为它仅用于扩展_driver而不是_utility ...两个完全不同的功能。


工作解决方案(不理想)

我发现的唯一可行解决方案是编辑CodeIgniter系统文件。出于显而易见的原因,我不想这样做。

&#34;破坏&#34;位于system/database/drivers/mysqli/mysqli_utility.php的备份功能如下......

function _backup($params = array())
{
    // Currently unsupported
    return $this->db->display_error('db_unsuported_feature');
}

有一个Ellis Lab线程显示了一个有效的函数......

https://ellislab.com/forums/viewthread/194645/

我通过使用新的_backup函数编辑核心系统文件来实现它。

function _backup($params = array())
{
    // the working backup function is here
    .....
}

那么我还能/我应该做什么呢?

mysqli驱动程序不支持CodeIgniter的备份功能,我不允许扩展CodeIgniter数据库实用程序,除了编辑核心系统文件之外别无选择。我好像被卡住了,我来这里看看我是否遗漏了什么,或者我还能做些什么,而不是编辑核心系统文件。


编辑:请注意 CodeIgniter v3 中的数据库实用程序类完全支持mysqli

4 个答案:

答案 0 :(得分:3)

基于accepted solution by @RandomSeed ...

我从CodeIgniter的dbutil()类中获取了Loader函数,并将其完全复制到我的自定义MY_Loader扩展名中。

然后它将从任何驱动程序加载默认实用程序文件,我只是重定向它以检查我的application/libraries目录中是否存在我的自定义数据库实用程序文件。如果文件存在,请使用它,否则使用默认文件。

<强> MY_Loader.php

<?php class MY_Loader extends CI_Loader {

    public function dbutil()
    {

        if (! class_exists('CI_DB'))
        {
            $this->database();
        }

        $CI =& get_instance();

        // for backwards compatibility, load dbforge so we can extend dbutils off it
        // this use is deprecated and strongly discouraged
        $CI->load->dbforge();

        require_once(BASEPATH . 'database/DB_utility.php');

        // START custom >>

        // path of default db utility file
        $default_utility = BASEPATH . 'database/drivers/' . $CI->db->dbdriver . '/' . $CI->db->dbdriver . '_utility.php';

        // path of my custom db utility file
        $my_utility = APPPATH . 'libraries/MY_DB_' . $CI->db->dbdriver . '_utility.php';

        // set custom db utility file if it exists
        if (file_exists($my_utility))
        {
            $utility = $my_utility;
            $extend = 'MY_DB_';
        }
        else
        {
            $utility = $default_utility;
            $extend = 'CI_DB_';
        }

        // load db utility file
        require_once($utility);

        // set the class
        $class = $extend . $CI->db->dbdriver . '_utility';

        // << END custom

        $CI->dbutil = new $class();

    }

}

<强> application/libraries/MY_DB_mysqli_utility.php

<?php
    class MY_DB_mysqli_utility extends CI_DB_utility {

    // everything in here is same as default mysqli_utility
    ....

    // EXCEPT the _backup() function is my own

    function _backup($params = array())
    {
        //  my custom backup code
        ....

我对此解决方案非常满意,因为它使我的CodeIgniter核心文件完全不受影响。如果我移动或忘记使用我的自定义实用程序文件,它会无声地回退到默认驱动程序的实用程序文件。


编辑:请注意 CodeIgniter v3 中的数据库实用程序类完全支持mysqli,无需此解决方法。

答案 1 :(得分:2)

  

无法使用您自己的类扩展或替换数据库类。

这些类甚至不是final,所以我会忽略这个通知并派生出我自己的驱动程序(根据DB.php第140-143行):

  • system/database/drivers/中创建一个新文件夹,例如mysupersqli/
  • 创建一组文件mysupersqli_[driver|forge|result|utility].php
  • 在上述每个文件中,声明一个扩展其CI_DB_mysupersqli_[driver|forge|result|utility]对应的CI_DB_mysqli_*对象CI_DB_mysupersqli_driver::$dbdriver should be overriden的类system/database/drivers/mysqli,根据自己的喜好覆盖其余部分)
  • 或者,残酷的复制/粘贴/搜索和替换来自config/database.php的文件可能会更快(它也会使您的自定义驱动程序与内置的mysqli驱动程序无关,可能是也可能不是好事)
  • 现在您应该能够将{{1}}修改为新驱动程序

免责声明:未经测试:)

答案 2 :(得分:2)

涉及自定义加载器(Extending Database Drivers)的解决方案与此相关:扩展数据库驱动程序。您不能只使用*_driver类替换*_utility类。

$my_driver_file = APPPATH.'libraries/'.$my_driver.EXT; // *driver* required!!

相反,我会覆盖CI_Loader::dbutil() method。这样的事情应该有效:

public function dbutil()
{
    /* snip for brevity */
    $class = config_item('subclass_prefix').'DB_'.$db->dbdriver.'_utility';
    $filename = APPPATH.'libraries/'.$class.EXT;
    require_once($filename);
    /* snip for brevity */
 }

免责声明:未经测试:)

答案 3 :(得分:0)

由于内存和脚本超时,因为使用php进行数据库备份在某种程度上受到限制。 如何使用mysqldump创建一个使用mysqldump进行备份的cronjob?

但是,如果这不是一个选项,this可以帮助