Problem:
When I updated my CodeIgniter 2.2.0 application to use the mysqli
database drivers, it broke CodeIgniter's backup function of the Database Utility Class. Where I used to successfully get a database backup, I'm now getting an error...
Unsupported feature of the database platform you are using.
The error simply means that the CodeIgniter backup function from the Database Utility Class does not support mysqli
. As per the online docs, only MySQL is supported.
However, I prefer not to use the deprecated mysql
database driver.
Possible Workaround (not allowed):
I thought I could solve this by simply extending CodeIgniter's Database Utility class. However, CodeIgniter does not allow this as per documentation...
Note: The Database classes can not be extended or replaced with your own classes.
Another Workaround (fatal error):
EDIT: my answer and the accepted answer are based on this workaround.
This GitHub page describes a method for extending the Database Class by creating a MY_Loader
class to extend the core.
https://github.com/bcit-ci/CodeIgniter/wiki/Extending-Database-Drivers
However, when I attempted this solution, I got this fatal error...
Filename: core/MY_Loader.php, Line Number: 49
Fatal error: Call to undefined method CI_DB_mysqli_driver::where() in /home/account/codeigniter/system/libraries/Session.php on line 217
Line 49 is: $db =& new $my_driver(get_object_vars($db));
I am using the MY_Loader
exactly as described at the link above, and MY_DB_mysqli_utility
looks like this...
<?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
.....
}
}
(I'm not entirely sure if this GitHub workaround is failing because it's out of date, I overlooked something, or if it's because I'm trying to use it on CI_DB_mysqli_utility
instead of CI_DB_mysqli_driver
.)
EDIT: this workaround was failing because it was meant only for extending the _driver
and not the _utility
... two completely different functions.
A Working Solution (not ideal):
The only working solution I've found has been to edit the CodeIgniter System files. For obvious reasons, I'd prefer not to do this.
The "broken" backup function located at system/database/drivers/mysqli/mysqli_utility.php
is as follows...
function _backup($params = array())
{
// Currently unsupported
return $this->db->display_error('db_unsuported_feature');
}
There is an Ellis Lab thread that shows a function that works...
https://ellislab.com/forums/viewthread/194645/
I got it working by editing the core system file with the new _backup
function.
function _backup($params = array())
{
// the working backup function is here
.....
}
So what else can/should I do here?
CodeIgniter's backup function is not supported by the mysqli
driver, and I'm not allowed to extend the CodeIgniter Database Utility, leaving me with no alternative but to edit the core system files. I seem to be stuck and I'm coming here to see if I missed anything or if there's anything else I can do instead of editing the core system files.
EDIT: Note that the Database Utility Class in CodeIgniter v3 fully supports mysqli
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With