How to extend the CodeIgniter Database Utility Class How to extend the CodeIgniter Database Utility Class codeigniter codeigniter

How to extend the CodeIgniter Database Utility Class


Based on accepted solution by @RandomSeed...

I took the dbutil() function from CodeIgniter's Loader class and copied it exactly into my custom MY_Loader extension.

Then where it would load the default utility file from whichever driver, I simply redirected it to check for the existence of my custom database utility file located in my application/libraries directory. If the file exists, use it, otherwise use the default file.

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        ....

I'm very happy with this solution as it leaves my CodeIgniter core files completely untouched. If I move or forget to use my custom utility file, it silently falls back to the default driver's utility file.


EDIT: Note that the Database Utility Class in CodeIgniter v3 fully supports mysqli negating any need for this workaround.


The Database classes can not be extended or replaced with your own classes.

These classes are not even final, so I would just ignore this notice and derive my own driver (as per DB.php lines 140-143):

  • create a new folder in system/database/drivers/, e.g. mysupersqli/
  • create a set of files mysupersqli_[driver|forge|result|utility].php
  • in each above file, declare a class CI_DB_mysupersqli_[driver|forge|result|utility] that extends its CI_DB_mysqli_* counterpart (CI_DB_mysupersqli_driver::$dbdriver should be overriden, override the rest to your liking)
  • alternatively, a brutal copy/paste/search&replace of the files from system/database/drivers/mysqli might be quicker (it would also make your custom driver independant from the the built-in mysqli driver, which may or may not be a good thing)
  • now you should be able to modify config/database.php to your new driver

Disclaimer: not tested :)


The solution involving a custom loader (Extending Database Drivers) is relevant to just that: extending database drivers. You can't just replace a *_driver class with an *_utility class.

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

Instead, I would override the CI_Loader::dbutil() method. Something like this should work:

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 */ }

Disclaimer: not tested :)