简体   繁体   中英

Backup MySQL database with CodeIgniter

I have been looking into the user guide which came with CodeIgniter. I became very interested with the dbutil() method. Particularly the following line of code:

// Load the DB utility class
$this->load->dbutil();

// Backup your entire database and assign it to a variable
$backup =& $this->dbutil->backup(); 

// Load the file helper and write the file to your server
$this->load->helper('file');
write_file('/path/to/mybackup.gz', $backup); 

// Load the download helper and send the file to your desktop
$this->load->helper('download');
force_download('mybackup.gz', $backup); 

It is supposed to backup the currently loaded MySQL database. But unfortunately, it is not working and I get the following message:

A PHP Error was encountered

Severity: Notice

Message: Undefined property: CI_Loader::$dbutil

Filename: views/view.php

Line Number: 10

Fatal error: Call to a member function backup() on a non-object in C:\xampp\htdocs\CodeIgniter\application\views\view.php on line 10

What am I missing here? Any help would be really appreciated.

Try this, You can change format zip to gz if you like :)

$this->load->dbutil();

$prefs = array(     
    'format'      => 'zip',             
    'filename'    => 'my_db_backup.sql'
    );


$backup =& $this->dbutil->backup($prefs); 

$db_name = 'backup-on-'. date("Y-m-d-H-i-s") .'.zip';
$save = 'pathtobkfolder/'.$db_name;

$this->load->helper('file');
write_file($save, $backup); 


$this->load->helper('download');
force_download($db_name, $backup);

doing that using php will only work for very small databases. You will very fast run into memory limits - if you increase that other performance problems.

What works best is to create a dump using mysqldump:

header('Content-type: application/force-download');
header('Content-Disposition: attachment; filename="dbbackup.sql.gz"');
passthru("mysqldump --user=xx --host=xx --password=xx dbname | gzip");

of course you must have the required permissions to do that.

function backup($fileName='db_backup.zip'){
    // Load the DB utility class
    $this->load->dbutil();

    // Backup your entire database and assign it to a variable
    $backup =& $this->dbutil->backup();

    // Load the file helper and write the file to your server
    $this->load->helper('file');
    write_file(FCPATH.'/downloads/'.$fileName, $backup);

    // Load the download helper and send the file to your desktop
    $this->load->helper('download');
    force_download($fileName, $backup);
}

Easy way to backup database using codeigniter

//load helpers

$this->load->helper('file');
$this->load->helper('download');
$this->load->library('zip');

//load database
$this->load->dbutil();

//create format
$db_format=array('format'=>'zip','filename'=>'backup.sql');

$backup=& $this->dbutil->backup($db_format);

// file name

$dbname='backup-on-'.date('d-m-y H:i').'.zip';
$save='assets/db_backup/'.$dbname;

// write file

write_file($save,$backup);

// and force download
force_download($dbname,$backup);

If you are lucky enough to have one of the exec() , shell_exec() , system() or passthru() enabled on your server. Maybe you would want to use the following:

public function db_backup()
{
    $DBUSER=$this->db->username;
    $DBPASSWD=$this->db->password;
    $DATABASE=$this->db->database;

    $filename = $DATABASE . "-" . date("Y-m-d_H-i-s") . ".sql.gz";
    $mime = "application/x-gzip";

    header( "Content-Type: " . $mime );
    header( 'Content-Disposition: attachment; filename="' . $filename . '"' );

    // $cmd = "mysqldump -u $DBUSER --password=$DBPASSWD $DATABASE | gzip --best";   
    $cmd = "mysqldump -u $DBUSER --password=$DBPASSWD --no-create-info --complete-insert $DATABASE | gzip --best";

    passthru( $cmd );

    exit(0);
}

Try this one...it has been tested...if you are going to use mysqli then it will works fine...you may put your code in your controller or model but i suggest to keep this one in your_model & call this function from your_controller...

public function db_backup()
{
       $this->load->dbutil();   
       $backup =& $this->dbutil->backup();  
       $this->load->helper('file');
       write_file('your_file_path/your_DB.zip', $backup); 
}

I am extremely new to CodeIgniter but I succeeded to do this backup. Try this, it will work successfully and is very easy to implement. Write the code in your controller and call the function from your view page which use for backup. Get set, go and you are done.

function dbbackup()
{
    $this->load->dbutil();   
    $backup =& $this->dbutil->backup();  
    $this->load->helper('file');
    write_file('<?php echo base_url();?>/downloads', $backup);
    $this->load->helper('download');
    force_download('mybackup.gz', $backup);
}

For your full application backup, do the same procedure with the following code:

function backup()
{
    $this->load->helper('download');
    $this->load->library('zip'); 
    $time = time(); 
    $this->zip->read_dir('D:xampp/htdocs/wms/');
    $this->zip->download('my_backup.'.$time.'.zip');
}

Here you can use any path of your choice.

public function db_backup()
{
    $this->load->helper('url');
    $this->load->helper('file');
    $this->load->helper('download');
    $this->load->library('zip');
    $this->load->dbutil();
    $db_format=array('format'=>'zip','filename'=>'my_db_backup.sql');
    $backup=& $this->dbutil->backup($db_format);
    $dbname='backup-on-'.date('Y-m-d').'.zip';
    $save='assets/db_backup/'.$dbname;
    write_file($save,$backup);
    force_download($dbname,$backup);

}`

$content = 'SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; START TRANSACTION; SET time_zone = "+00:00";';

    if($tables = $this->db->list_tables()){
        foreach($tables as $table){
            $content .= ' DROP TABLE IF EXISTS `' . $table . '`;';
            $content .= $this->db->query('SHOW CREATE TABLE ' . $table)->row_array()['Create Table'] . ';'; 
            $fields = $this->db->list_fields($table);
            $table_data = $this->db->query('SELECT * FROM ' . $table)->result_array();
            $insert_field = '';
            $insert_values = '';
            if($fields && $table_data){
                $insert_field .= 'INSERT INTO `' . $table . '` (';

                foreach($fields as $field){
                    $insert_field .= '`' . $field . '`,';
                }
                $insert_field = substr($insert_field,0,-1);
                $insert_field .= ')';
                
                $insert_values .= ' VALUES ';
                foreach($table_data as $table_row){
                    $insert_values .= '(' ;
                    foreach($table_row as $column => $value){
                        $insert_values .= "'" . addslashes($value) . "',";
                    }
                    $insert_values = substr($insert_values,0,-1);
                    $insert_values .= '),';
                }
                $insert_values = substr($insert_values,0,-1) . '; ';
            }
            $content .= $insert_field . $insert_values;
        }
    }
    $file_path = "./uploads/backup-" . date('Y-m-d') . ".sql";
    $myfile = fopen($file_path, "w");
    fwrite($myfile, $content);
    fclose($myfile);

These lines have been grabbed from codeigniters documentation:

Important: In order to initialize the Utility class, your database driver must already be running, since the utilities class relies on it.

Please check if your database class is loaded or not when you call this function. Or you can put this line before loading the dbutil class $this->load->database();

Try this!

$username = "root";
$password = "root";
$hostname = "localhost";
$dbname   = "raas";

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($dbname . "_" .date("Y-m-d_H-i-s").".sql"));

$command = "C:\AppServ\MySQL\bin\mysqldump --add-drop-table --host=$hostname   --user=$username --password=$password ".$dbname;

system($command);

The problem is that you are trying to backup the database very early during bootstrapping.

I ran into the same problem when I tried to hack CodeIgniter into backing up my database using:

$prefs = array(
            'ignore'=> array('codes_cdt','codes_cpt','codes_icd10_dx_order','codes_icd10_pcs_order','pharma'),
            'format'=>'gzip','filename','add_drop'=> TRUE,'add_insert'=>TRUE,'newline'=> "\n");

$filename = APPPATH.'\\backups\\' .'backup-' . date('d-m-Y') . ' .gz';
if(!file_exists($filename)){
    get_instance()->load->dbutil();
    file_put_contents( $filename, $this->dbutil->backup($prefs));
}

at the bottom of my config.php file.

Move this to a model an allow it to autoload, and you will be fine.

 <?

// Try this one, this works FOR both codeigniter and core PHP

            public function Export_Database()
                {
                    date_default_timezone_set('GMT');
                   // Load the file helper in codeigniter
                    $this->load->helper('file');


            $con = mysqli_connect("localhost","username","password","databasename");

            $tables = array();
            $query = mysqli_query($con, 'SHOW TABLES');
            while($row = mysqli_fetch_row($query)){
                 $tables[] = $row[0];
            }

            $result = 'SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";';
            $result .= 'SET time_zone = "+00:00";';

            foreach($tables as $table){
            $query = mysqli_query($con, 'SELECT * FROM `'.$table.'`');
            $num_fields = mysqli_num_fields($query);

            $result .= 'DROP TABLE IF EXISTS '.$table.';';
            $row2 = mysqli_fetch_row(mysqli_query($con, 'SHOW CREATE TABLE `'.$table.'`'));
            $result .= "\n\n".$row2[1].";\n\n";

            for ($i = 0; $i < $num_fields; $i++) {
            while($row = mysqli_fetch_row($query)){
               $result .= 'INSERT INTO `'.$table.'` VALUES(';
                 for($j=0; $j<$num_fields; $j++){
                   $row[$j] = addslashes($row[$j]);
                   $row[$j] = str_replace("\n","\\n",$row[$j]);
                if(isset($row[$j])){
                       $result .= '"'.$row[$j].'"' ; 
                    }else{ 
                        $result .= '""';
                    }
                    if($j<($num_fields-1)){ 
                        $result .= ',';
                    }
                }
                $result .= ");\n";
            }
            }
            $result .="\n\n";
            }

            //Create Folder
            $folder = 'database/';
            if (!is_dir($folder))
            mkdir($folder, 0777, true);
            chmod($folder, 0777);

            $date = date('m-d-Y'); 
            $filename = $folder."db_filename_".$date; 

            $handle = fopen($filename.'.sql','w+');
            fwrite($handle,$result);
            fclose($handle);
            redirect('Dashboard');           


                } // end Export_Database function
            ?>
// to intialize the path split the real path by dot .
        public function init_path($string){
            $array_path =  explode('.', $string);
            $realpath  = ''; 
            foreach ($array_path as $p)
            {

                $realpath .= $p;
                $realpath .= '/';
            }
            return $realpath;

        }

        // backup database function         
        public function archive_database($host = '',$user ='',$pass ='',$name ='', $path = '' , $download_allow = false ,       $tables=false, $backup_name=false){ 
            $CI = &get_instance();
            $CI->load->database();
            if($path != '')
            {
                $path = realpath($this->init_path($path));

            }else{
                if (!is_dir('archives/'))
            mkdir('archives/', 0777);
                $path = realpath($this->init_path('archives'));
            }
            if($host == '')
            {
                $host = $CI->db->hostname;

            }
            if($user == '')
            {
                $user = $CI->db->username;

            }
            if($pass == '')
            {
                $pass = $CI->db->password;

            }
            if($name == '')
            {
                $name = $CI->db->database;

            }

            set_time_limit(3000); 
            $mysqli = new mysqli($host,$user,$pass,$name); 
            $mysqli->select_db($name);
            $mysqli->query("SET NAMES 'utf8'");
            $queryTables = $mysqli->query('SHOW TABLES');
            while($row = $queryTables->fetch_row()) { $target_tables[] = $row[0]; } 
            if($tables !== false)
                { $target_tables = array_intersect( $target_tables, $tables); } 
            $content = "SET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\";\r\nSET time_zone = \"+00:00\";\r\n\r\n\r\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;\r\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;\r\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;\r\n/*!40101 SET NAMES utf8 */;\r\n--\r\n-- Database: `".$name."`\r\n--\r\n\r\n\r\n";
            foreach($target_tables as $table){
                if (empty($table)){ continue; } 
                $result = $mysqli->query('SELECT * FROM `'.$table.'`');
                $fields_amount=$result->field_count; 
                $rows_num=$mysqli->affected_rows; 
                $res = $mysqli->query('SHOW CREATE TABLE '.$table);
                $TableMLine=$res->fetch_row(); 
                $content .= "\n\n".$TableMLine[1].";\n\n";
                for ($i = 0, $st_counter = 0; $i < $fields_amount;   $i++, $st_counter=0) {
                    while($row = $result->fetch_row())  { //when started (and every after 100 command cycle):
                        if ($st_counter%100 == 0 || $st_counter == 0 )  {$content .= "\nINSERT INTO ".$table." VALUES";}
                            $content .= "\n(";    for($j=0; $j<$fields_amount; $j++){ $row[$j] = str_replace("\n","\\n", addslashes($row[$j]) ); if (isset($row[$j])){$content .= '"'.$row[$j].'"' ;}  else{$content .= '""';}     if ($j<($fields_amount-1)){$content.= ',';}   }        $content .=")";
                        //every after 100 command cycle [or at last line] ....p.s. but should be inserted 1 cycle eariler
                        if ( (($st_counter+1)%100==0 && $st_counter!=0) || $st_counter+1==$rows_num) {$content .= ";";} else {$content .= ",";} $st_counter=$st_counter+1;
                    }
                } $content .="\n\n\n";
            }
            $content .= "\r\n\r\n/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\r\n/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\r\n/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;";
            $backup_name = $backup_name ? $backup_name : $name."___(".date('H-i-s')."_".date('d-m-Y').")__rand".rand(1,11111111).".sql";

            $fileLocation = $path .'\\'. $backup_name;
            $file = fopen($fileLocation,"w");
            fwrite($file,$content);
            fclose($file);


            if($download_allow){
            ob_get_clean(); header('Content-Type: application/octet-stream');   header("Content-Transfer-Encoding: Binary"); header("Content-disposition: attachment; filename=\"".$backup_name."\"");
            }

            echo $content; exit;
        }
 public function backup(){
    $this->load->dbutil();
    $config = array(     
        'format'      => 'zip',             
        'filename'    => 'insert-file-name.sql'
    );

    $backup =& $this->dbutil->backup($config); 

    $db_name = 'backup-on-'. date("Y-m-d-H-i-s") .'.zip';
    $save = 'uploads/'.$db_name;

    $this->load->helper('file');
    write_file($save, $backup); 
    $this->load->helper('download');
    force_download($db_name, $backup);

}

无需在路径中添加base_url()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM