数据库实用程序 - 备份不使用MySQLi -Codeigniter

时间:2014-06-13 04:41:12

标签: mysql codeigniter mysqli

下面是我的数据库备份代码。

$this->load->database();
$this->load->dbutil();
$backup =& $this->dbutil->backup();

$prefs = array(
    'format'      => 'txt',            
    'filename'    => 'mybackup.sql', );

$path=$this->config->base_url()."database/";
$this->load->helper('file');
write_file($path, $backup); 
$this->load->helper('download');
force_download('mybackup.gz', $backup);

使用

时效果很好
$db['default']['dbdriver'] = 'mysql';

但它给出了错误

$db['default']['dbdriver'] = 'mysqli';

error:Unsupported feature of the database platform you are using.

如何使用“mysqli”我需要在我的项目中支持mysqli。

3 个答案:

答案 0 :(得分:8)

这对我不利,然后我打开文件" system \ database \ drivers \ mysqli \ mysqli_utility.php"并改变功能" _backup"对此:

/**
 * MySQLi Export
 *
 * @access  private
 * @param   array   Preferences
 * @return  mixed
 */
function _backup($params = array())
{
    // Currently unsupported
    //---return $this->db->display_error('db_unsuported_feature');

    if (count($params) == 0)
    {
        return FALSE;
    }

    // Extract the prefs for simplicity
    extract($params);

    // Build the output
    $output = '';
    foreach ((array)$tables as $table)
    {
        // Is the table in the "ignore" list?
        if (in_array($table, (array)$ignore, TRUE))
        {
            continue;
        }

        // Get the table schema
        $query = $this->db->query("SHOW CREATE TABLE `".$this->db->database.'`.`'.$table.'`');

        // No result means the table name was invalid
        if ($query === FALSE)
        {
            continue;
        }

        // Write out the table schema
        $output .= '#'.$newline.'# TABLE STRUCTURE FOR: '.$table.$newline.'#'.$newline.$newline;

        if ($add_drop == TRUE)
        {
            $output .= 'DROP TABLE IF EXISTS '.$table.';'.$newline.$newline;
        }

        $i = 0;
        $result = $query->result_array();
        foreach ($result[0] as $val)
        {
            if ($i++ % 2)
            {
                $output .= $val.';'.$newline.$newline;
            }
        }

        // If inserts are not needed we're done...
        if ($add_insert == FALSE)
        {
            continue;
        }

        // Grab all the data from the current table
        $query = $this->db->query("SELECT * FROM $table");

        if ($query->num_rows() == 0)
        {
            continue;
        }

        // Fetch the field names and determine if the field is an
        // integer type.  We use this info to decide whether to
        // surround the data with quotes or not

        $i = 0;
        $field_str = '';
        $is_int = array();
        while ($field = mysqli_fetch_field($query->result_id))
        {
            // Most versions of MySQL store timestamp as a string
            $is_int[$i] = (in_array(
                                    //strtolower(mysqli_field_type($query->result_id, $i)),
                                    strtolower($field->type),
                                    array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'),
                                    TRUE)
                                    ) ? TRUE : FALSE;

            // Create a string of field names
            $field_str .= '`'.$field->name.'`, ';
            $i++;
        }

        // Trim off the end comma
        $field_str = preg_replace( "/, $/" , "" , $field_str);


        // Build the insert string
        foreach ($query->result_array() as $row)
        {
            $val_str = '';

            $i = 0;
            foreach ($row as $v)
            {
                // Is the value NULL?
                if ($v === NULL)
                {
                    $val_str .= 'NULL';
                }
                else
                {
                    // Escape the data if it's not an integer
                    if ($is_int[$i] == FALSE)
                    {
                        $val_str .= $this->db->escape($v);
                    }
                    else
                    {
                        $val_str .= $v;
                    }
                }

                // Append a comma
                $val_str .= ', ';
                $i++;
            }

            // Remove the comma at the end of the string
            $val_str = preg_replace( "/, $/" , "" , $val_str);

            // Build the INSERT string
            $output .= 'INSERT INTO '.$table.' ('.$field_str.') VALUES ('.$val_str.');'.$newline;
        }

        $output .= $newline.$newline;
    }

    return $output;

}

如果你需要改变......

更改所有" mysql _..."到" mysqli ......"

和行

strtolower(mysqli_field_type($query->result_id, $i)),

到此

strtolower($field->type),                       

中提琴!那太棒了......

答案 1 :(得分:1)

您的mysqli驱动程序不支持此功能。

参考: http://ellislab.com/forums/viewthread/194645/#979255

答案 2 :(得分:1)

这是备份任何大小的所有数据库的函数的扩展。

此代码将使用文件系统(缓存文件夹)和SQL LIMITS删除导出数据库时的PHP内存限制。

我希望这对某人有用。

替换功能 _backup($ params = array())

文件:system / drivers / mysqli / mysqli_utility.php

/**
 * MySQLi Export
 *
 * @access  private
 * @param   array   Preferences
 * @return  mixed
 */
function _backup_old($params = array())
{
    // Currently unsupported
    return $this->db->display_error('db_unsuported_feature');
}

/**
* MySQLi Export
*
* @access  private
* @param   array   Preferences
* @return  mixed
*/
function _backup($params = array())
{
    // Currently unsupported
    //---return $this->db->display_error('db_unsuported_feature');

    if (count($params) == 0)
    {
        return FALSE;
    }

    // Extract the prefs for simplicity
    extract($params);

    // Build the output
    $output = '';
    foreach ((array)$tables as $table)
    {

        // Temp file to reduce change of OOM Killer
        $tempfilepath = APPPATH . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR;
        $tempfile = $tempfilepath . 'dbbkp_tmp_' . time() . '.sql';

        // Is the table in the "ignore" list?
        if (in_array($table, (array)$ignore, TRUE))
        {
            continue;
        }

        // Get the table schema
        $query = $this->db->query("SHOW CREATE TABLE `".$this->db->database.'`.`'.$table.'`');

        // No result means the table name was invalid
        if ($query === FALSE)
        {
            continue;
        }

        // Write out the table schema
        $output .= '#'.$newline.'# TABLE STRUCTURE FOR: '.$table.$newline.'#'.$newline.$newline;

        if ($add_drop == TRUE)
        {
            $output .= 'DROP TABLE IF EXISTS '.$table.';'.$newline.$newline;
        }

        $i = 0;
        $result = $query->result_array();
        foreach ($result[0] as $val)
        {
            if ($i++ % 2)
            {
                $output .= $val.';'.$newline.$newline;
            }
        }

        // Write $output to the $filename file
        file_put_contents( $filename, $output, LOCK_EX );
        $output = '';

        // If inserts are not needed we're done...
        if ($add_insert == FALSE)
        {
            continue;
        }

        // Grab all the data from the current table
        //$query = $this->db->query("SELECT * FROM $table"); // OLD
        $countResult = $this->db->query("SELECT COUNT(*) AS `count` FROM " . $table . ";");
        $countReturn = $countResult->result_array();
        $totalCount = $countReturn[0]['count'];

        //if ($query->num_rows() == 0) // OLD
        if ($totalCount == 0)
        {
            continue;
        }

        // Chunk Vars
        $chunkSize = 10000;
        $from      = 0;
        $resultArray = array();

        if (isset($chunk_size))
        {
            $chunkSize = $chunk_size;
        }

        // Write out the table schema
        $output .= '#'.$newline.'# TABLE DATA FOR: '.$table.$newline.'#'.$newline.$newline;

        // Write $output to the $filename file
        file_put_contents( $filename, $output, FILE_APPEND | LOCK_EX );

        // Fetch the field names and determine if the field is an
        // integer type.  We use this info to decide whether to
        // surround the data with quotes or not
        $query = $this->db->query("SELECT * FROM " . $table . " LIMIT 1;");
        $i = 0;
        $field_str = '';
        $is_int = array();
        while ($field = mysqli_fetch_field($query->result_id))
        {
            // Most versions of MySQL store timestamp as a string
            $is_int[$i] = (in_array(
                                    //strtolower(mysqli_field_type($query->result_id, $i)),
                                    strtolower($field->type),
                                    array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'),
                                    TRUE)
                                    ) ? TRUE : FALSE;

            // Create a string of field names
            $field_str .= '`'.$field->name.'`, ';
            $i++;
        }

        // Trim off the end comma
        $field_str = preg_replace( "/, $/" , "" , $field_str);

        // Pull the data in chunks
        while($from < $totalCount)
        {
            // empty $output
            $output = '';

            // Execute a limited query:
            $dataChunkQuery = $this->db->query('SELECT * FROM ' . $table . ' LIMIT ' . $from . ', ' . $chunkSize . ';');
            $dataChunkRows = $dataChunkQuery->result_array();

            // Increase $from:        
            $from += $chunkSize;

            // Build the insert string
            //foreach ($query->result_array() as $row) // OLD
            //var_dump($resultArray); die();
            foreach ($dataChunkRows as $row)
            {
                $val_str = '';

                $i = 0;
                foreach ($row as $v)
                {
                    // Is the value NULL?
                    if ($v === NULL)
                    {
                        $val_str .= 'NULL';
                    }
                    else
                    {
                        // Escape the data if it's not an integer
                        if ($is_int[$i] == FALSE)
                        {
                            $val_str .= $this->db->escape($v);
                        }
                        else
                        {
                            $val_str .= $v;
                        }
                    }

                    // Append a comma
                    $val_str .= ', ';
                    $i++;
                }

                // Remove the comma at the end of the string
                $val_str = preg_replace( "/, $/" , "" , $val_str);

                // Build the INSERT string
                $output .= 'INSERT INTO '.$table.' ('.$field_str.') VALUES ('.$val_str.');'.$newline;
            }

            // Write $output to the $filename file
            file_put_contents( $filename, $output, FILE_APPEND | LOCK_EX );

            sleep(1); // used to help reduce the CPU load
        }

    }

    if( file_exists($filename) ) {
        return true;
    } else {
        return false;
    }

}

为数据库备份构建的CI模型

FILE:models / databasebackup_model.php

<?php
/**
* Database Backup
* - Used to make backups of the database system
* @author Adan Rehtla <adan.rehtla@aamcommercial.com.au>
*/
class Databasebackup_model extends API_Model {

    private $CI;
    private $lpFilePath = APPPATH . 'cache/backup/';

    // Tables to ignore when doing a backup
    private $laIgnoreTables = array(
        'ci_sessions',
        'any_other_tables_to_ignore'
    );




    /**
     * Constructor
     * @author Adan Rehtla <adan.rehtla@aamcommercial.com.au>
     */
    function __construct() {
        parent::__construct();
        $this->CI = &get_instance();
    }



    /**
     * Check and empty the cache location for storing the backups during transit
     * @author Adan Rehtla <adan.rehtla@aamcommercial.com.au>
     * @return json                     Result
     */
    public function check_cache() {

        $arrRet = false;

        if( ! file_exists( $this->lpFilePath ) ) {
            $arrRet = mkdir( $this->lpFilePath );
            $arrRet = true;
        }

        $files = glob( $this->lpFilePath . '*' ); // get all file names present in folder
        foreach( $files as $file ){ // iterate files
            if( is_file( $file ) ) unlink( $file ); // delete the file
        }

        return (object) $arrRet;
    }



    /**
     * Build a list of tables to backup
     * @author Adan Rehtla <adan.rehtla@aamcommercial.com.au>
     * @return json                     Result
     */
    public function find_tables() {

        $arrRet = false;

        if( $this->database('db_read') ) {   

            $this->db_read->_protect_identifiers = FALSE;
            $this->db_read->start_cache();
            $this->db_read->distinct();
            $this->db_read->select("table_name");
            $this->db_read->from("information_schema.columns");
            $this->db_read->where("table_schema", $this->db->dbprefix . $this->db->database);
            $this->db_read->stop_cache();

            // Get List of all tables to backup
            $laTableNameResult = $this->db_read->get()->result();

            $this->db_read->flush_cache();

            if( !empty($laTableNameResult) ) {
                foreach($laTableNameResult as $loTableName) {
                    if( ! in_array( $loTableName->table_name, $this->laIgnoreTables ) ) {
                        $arrRet[] = $loTableName->table_name;
                    }
                }
            }

            $this->db_read->_protect_identifiers = TRUE;
        }

        return (object) $arrRet;
    }



    /**
     * Backup the database to Amazon S3
     * @author Adan Rehtla <adan.rehtla@aamcommercial.com.au>
     * @param  interger $lpUserId       Logged in User ID
     * @return json                     Result
     */
    public function backup() {

        ini_set('max_execution_time', 3600); // 3600 seconds = 60 minutes
        ini_set('memory_limit', '-1'); // unlimited memory
        //error_reporting(E_ALL); // show errors
        //ini_set('display_errors', 1); // display errors

        $arrRet = array();

        $lpBackupCount = 0;
        $zipNumFiles = 0;
        $zipStatus = 0;

        if( $this->database('db_read') ) {

            $this->db->save_queries = false;

            $this->load->dbutil( $this->db_read, TRUE );

            $laBackupTables = $this->find_tables();

            if( !empty($laBackupTables) && $this->check_cache() ) {

                foreach($laBackupTables as $lpTableName) {

                    $lpFilename = $this->lpFilePath . 'backup-' . $lpTableName . '-' . date('Ymd-His') . '.sql';

                    $prefs = array(
                        'tables'                => $lpTableName,
                        'format'                => 'sql',
                        'filename'              => $lpFilename,
                        'add_drop'              => TRUE,
                        'add_insert'            => TRUE,
                        'newline'               => "\n",
                        'foreign_key_checks'    => TRUE,
                        'chunk_size'            => 1000
                    );

                    if( !file_exists( $lpFilename ) ){
                        if( $this->dbutil->backup( $prefs ) ) {
                            $lpBackupCount++;
                        }
                    }

                    sleep(1); // used to help reduce the CPU load

                    //break; // used to debug and testing to only process the first database table
                }

                try {
                    // ZIP up all the individual GZIPs
                    $zip = new ZipArchive();
                    $zip_file = $this->lpFilePath . '-' . date('Ymd-His') . '.zip';
                    $zip_files = glob( $this->lpFilePath . 'backup-*' ); // get all file names present in folder starting with 'backup-'

                    if( $zip->open( $zip_file, ZIPARCHIVE::CREATE ) !== TRUE ) {
                        exit("cannot open <$zip_file>\n");
                    }

                    if( !empty($zip_files) ) {
                        foreach( $zip_files as $file_to_zip ) { // iterate files
                            $zip->addFile( $file_to_zip, basename( $file_to_zip ) );
                        }
                    }

                    $zipNumFiles = $zip->numFiles;
                    $zipStatus = $zip->status;
                    $zip->close();

                } catch (Vi_exception $e) {
                    print( strip_tags( $e->errorMessage() ) );
                }

                // Upload the file to Amazon S3    
                // REMOVED AWS S3 UPLOAD CODE
                // REMOVED AWS S3 UPLOAD CODE
                // REMOVED AWS S3 UPLOAD CODE

                // Clean up cache files
                $this->check_cache();
            }

            $this->db->save_queries = true;

        }

        if( !empty($lpBackupCount) && !empty($zip) && !empty($zip_file) ) {
            return (object) array( 'success'=>true, 'totalTables'=>$lpBackupCount, 'zipNumFiles'=>$zipNumFiles, 'zipStatus'=>$zipStatus, 'zipFile'=>$zip_file );
        } else {
            return (object) array( 'success'=>false );
        }
    }




}

<强> USAGE:

$this->load->model('databasebackup_model');
$laResult = $this->databasebackup_model->backup();