CodeIgniter Forums
Codeigniter dbutil backup question - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Using CodeIgniter (https://forum.codeigniter.com/forumdisplay.php?fid=5)
+--- Forum: General Help (https://forum.codeigniter.com/forumdisplay.php?fid=24)
+--- Thread: Codeigniter dbutil backup question (/showthread.php?tid=62373)



Codeigniter dbutil backup question - wolfgang1983 - 07-07-2015

I am creating a backup controller form where I can select and unselect table names that I want to back up.

As shown here


PHP Code:
public function backup_database() {
$post_backup $this->input->post('backup[]');

if (!isset(
$post_backup)) {
        
$this->session->set_flashdata('error''Warning: You must select at least one table to backup!');
        
} else {

$this->output->set_header('Pragma: public');
$this->output->set_header('Expires: 0');
$this->output->set_header('Content-Description: File Transfer');
$this->output->set_header('Content-Type: application/octet-stream');
$this->output->set_header('Content-Disposition: attachment; filename=' $this->db->database '_' date('Y-m-d_H-i-s'time()) . '_backup.sql');
$this->output->set_header('Content-Transfer-Encoding: binary');

$this->output->append_output($this->backup_codeigniter($post_backup));

}




Currently I have to add each table name manually like in code below


PHP Code:
public function backup_codeigniter($tables) {
$this->load->dbutil();

$prefs = array(
'tables' => array('user'), 
'ignore' => array(),
'format' => 'txt',
'filename' => $this->db->database .' 'date("Y-m-d-H-i-s").'-backup.sql' 
'add_drop' => TRUE,
'add_insert' => TRUE,
'newline' => "\n" 
);

return 
$this->dbutil->backup($prefs);



I have passed a variable called $tables on the model function.

Question: Instead of me entering the table name manually, How can I pass that variable correct so I do not have to enter each table name manually. Do I need to use array? Is it safe to just have 'tables' => $tables


RE: Codeigniter dbutil backup question - mwhitney - 07-07-2015

Although it's not the best example I could come up with given some time (though I'm responsible for much of the code, and certainly for what I consider the most cringe-worthy portions of it), I would recommend looking at how Bonfire does this:
https://github.com/ci-bonfire/Bonfire/tree/develop/bonfire/modules/database

To answer your question, though, if $tables is the input to a public method, especially in a controller, you need to do at least some basic checking to make sure it's safe. At the least, check that it's an array. The safest way to handle it would probably be to remove any entry in the array which is not also in the array of table names returned by $this->db->list_tables(). In the worst case, you can pass an empty array in the 'tables' key to get the dbutil->backup() to generate a backup of all tables in the database (of course, if you don't want that to happen, be sure to check for it).


RE: Codeigniter dbutil backup question - skunkbad - 07-07-2015

You could also just use mysqldump through PHP's exec function:

http://dba.stackexchange.com/questions/9306/how-do-you-mysqldump-specific-tables

Take the result and log it, SFTP it to another server, email it to yourself, etc. I think this only works on Linux and Mac, but not sure about Windows (if that matters to you).


RE: Codeigniter dbutil backup question - wolfgang1983 - 07-08-2015

(07-07-2015, 07:39 AM)mwhitney Wrote: Although it's not the best example I could come up with given some time (though I'm responsible for much of the code, and certainly for what I consider the most cringe-worthy portions of it), I would recommend looking at how Bonfire does this:
https://github.com/ci-bonfire/Bonfire/tree/develop/bonfire/modules/database

To answer your question, though, if $tables is the input to a public method, especially in a controller, you need to do at least some basic checking to make sure it's safe. At the least, check that it's an array. The safest way to handle it would probably be to remove any entry in the array which is not also in the array of table names returned by $this->db->list_tables(). In the worst case, you can pass an empty array in the 'tables' key to get the dbutil->backup() to generate a backup of all tables in the database (of course, if you don't want that to happen, be sure to check for it).

I have been working on database backup and repair have now got it all working just a few tweaks to do now.


PHP Code:
<?php

class Backup extends MX_Controller {
    private 
$error = array();

    public function 
__construct() {
        
parent::__construct();
        
$this->load->library('admin/users');
        
$this->load->model('admin/tool/model_tool_backup');
        
$this->load->library('form_validation');
    }

    public function 
restore() {
        
$config['upload_path'] = BASEPATH './upload/';
        
$config['allowed_types'] = 'gif|jpg|png|sql';
        
$config['max_size']    = '100000';
        
$config['max_width'] = '0';
        
$config['max_height'] = '0';
        
$config['overwrite'] = TRUE;

        
$this->load->library('upload'$config);

        if ( ! 
$this->upload->do_upload('import')) {

            
$this->error['warning'] = $this->upload->display_errors();

            
$this->index();

            
$content false;

        } else {

            
$content file_get_contents($_FILES['import']['tmp_name']);

            if (
$content) {

                
$this->restore_database($content);

                
$this->session->set_flashdata('success''You have successfully repaired your database');

                
redirect('admin/tool/backup');

            } else {

                
$this->error['warning'] = $this->upload->display_errors();

                
$this->index();
            }
            
        }

        return !
$this->error;
    }

    public function 
index() {
        
$data['tables'] = $this->model_tool_backup->get_tables();

        if ((
$this->input->server('REQUEST_METHOD') == 'POST') && $this->validate()) {
            
            
$this->backup_codeigniter($this->input->post('tables'));
        }

        if (isset(
$this->error['warning'])) {
            
$data['error_warning'] = $this->error['warning'];
        } else {
            
$data['error_warning'] = '';
        }

        if (isset(
$this->error['tables'])) {
            
$data['error_tables'] = $this->error['tables'];
        } else {
            
$data['error_tables'] = '';
        }

        
$data['sidebar'] = Modules::run('admin/common/sidebar/index');
        
$data['navbar'] = Modules::run('admin/common/navbar/index');
        
$data['header'] = Modules::run('admin/common/header/index');
        
$data['footer'] = Modules::run('admin/common/footer/index');

        
$this->load->view('tool/backup_view'$data);

    }

    public function 
validate() {
        if (!isset(
$_POST['tables'])) {
            
$this->error['tables'] = 'You must select at least one item';
        }

        return !
$this->error;
    }



Model Functions


PHP Code:
public function backup_codeigniter($tables) {
        
$this->load->dbutil();

 
          $prefs = array(
 
           'tables' => $tables
 
           'ignore' => array(),
 
           'format' => 'txt',
 
           'filename' => $this->db->database '_' date('Y-m-d_H-i-s'time()) . '_backup.sql',
 
           'add_drop' => TRUE,
 
           'add_insert' => TRUE,
 
           'newline' => "\n" 
 
       );

 
       $sql $this->dbutil->backup($prefs);

 
       $data $sql;

 
       $backup_path BASEPATH 'downloads/backup/'$prefs['filename'];

        if (
write_file($backup_path$data)) {
            return 
true 
        
} else {
            return 
false;
        }
    }

    public function 
restore_database($sqls) {
        foreach (
explode(";\n"$sqls) as $sql) {
            
$sql trim($sql);

            if (
$sql) {
                
$this->db->query($sql);
            }
        }
    }