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 itsCI_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 :)