How to do a dump of a MySQL database with PHP?

8

Currently, to export only the structure of a particular database, I use the following:

mysqldump -h host -u usuario --no-data --database banco > dump.sql -psenha

This generates an SQL file, all solved. However, this is a manual process that costs me time, and I forget to do so, so I thought about doing a PHP script to automate it inside my system. The problem is I do not know how to do that.

I would like to know if there is any specific SQL command so I can generate this file. The requirement to be in PHP is that I may need to run this on a shared server, there would have several restrictions of other languages (such as shell script, use mysqldump itself, etc.).

    
asked by anonymous 05.02.2014 / 06:26

7 answers

2

I ended up getting a solution in PHP itself, based on the script of the site posted by @Gabriel Santos. Following:

class DatabaseDump {
    private $db;
    private $host, $user, $pass, $dbname;
    private $sql, $removeAI;

    public function __construct($host, $user, $pass, $dbname) {
        $this->host = $host;
        $this->user = $user;
        $this->pass = $pass;
        $this->dbname = $dbname;
        $this->removeAI = true;

        try {
            $this->db = new PDO('mysql:dbname='.$dbname.';host='.$host, $user, $pass);
            $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch(PDOException $e) {
            echo 'Connection failed: ' . $e->getMessage();          
            die;
        }
    }

    private function ln($text = '') {
        $this->sql = $this->sql . $text . "\n";
    }

    public function dump($file) {
        $this->ln("SET FOREIGN_KEY_CHECKS=0;\n");

        $tables = $this->db->query('SHOW TABLES')->fetchAll(PDO::FETCH_BOTH);

        foreach ($tables as $table) {
            $table = $table[0];
            $this->ln('DROP TABLE IF EXISTS ''.$table.'';');

            $schemas = $this->db->query("SHOW CREATE TABLE '{$table}'")->fetchAll(PDO::FETCH_ASSOC);

            foreach ($schemas as $schema) {
                $schema = $schema['Create Table'];
                if($this->removeAI) $schema = preg_replace('/AUTO_INCREMENT=([0-9]+)(\s{0,1})/', '', $schema);
                $this->ln($schema.";\n\n");
            }
        }

        file_put_contents($file, $this->sql);
    }
}
    
05.02.2014 / 14:06
3

Use the system function of PHP:

system('mysqldump -h host -u usuario --no-data --database banco > dump.sql -psenha');

See more information: link

And then just create a cronjob so the script runs once a day, or as you wish.

Here is a way to receive a copy of the database via email:

<?php
// Backup do site

$dbhost = 'localhost';
$dbuser = 'usuario_aqui';
$dbpass = 'password_aqui';
$dbname = 'database_aqui';

// Seu e-mail aqui
$sendto = 'Eu <[email protected]>';

// O remetente. Pode ser [email protected]
$sendfrom = 'Backup <[email protected]>';

// Assunto do e-mail
$sendsubject = 'Backup do site ' . date('d/m/Y');

// Corpo do e-mail
$bodyofemail = 'Backup diário do meu site';

$backupfile = 'Autobackup_' . date("Ymd") . '.sql';
$backupzip = $backupfile . '.tar.gz';
system("mysqldump -h $dbhost -u $dbuser -p$dbpass --lock-tables $dbname > $backupfile");
system("tar -czvf $backupzip $backupfile");

include('Mail.php');
include('Mail/mime.php');

$message = new Mail_mime();
$text = "$bodyofemail";
$message->setTXTBody($text);
$message->AddAttachment($backupzip);
$body = $message->get(array(
    'head_charset' => 'utf-8',
    'text_charset' => 'utf-8',
    'html_charset' => 'utf-8'
));
$extraheaders = array("From"=>"$sendfrom", "Subject"=>"$sendsubject");
$headers = $message->headers($extraheaders);
$mail = Mail::factory("mail");
$mail->send("$sendto", $headers, $body);

// Remover o arquivo do servidor (opcional)
unlink($backupzip);
unlink($backupfile);
?>

I do not remember who originally created the script above. I just remember changing the code a little bit.

    
05.02.2014 / 06:27
1

Use crontab to schedule backup jobs, as well as compress banks with gzip , which makes backups much smaller.

To schedule tasks with crontab , assuming you have the appropriate permissions on the system, run the command crontab -e .

For example, in my case I use crontab to schedule a daily backup of my bank:

0 * * * * /bin/sh /home/ec2-user/sh/backup_mysql.sh > /dev/null 2>&1

And within backup_mysql.sh I leave several commands mysqldump , in the model below:

mysqldump -u<usuario> -p<senha> <banco> | gzip > /home/ec2-user/backups/mysql/<banco>-'date '+%Y-%m-%d''.sql.gz

This is what I believe to be the best practice for a routine of periodic backups of databases. Try to use this template to find what works best for your purposes.

    
05.02.2014 / 13:00
1

mysqldump

It's not that simple. It is best to use mysqldump from PHP with shell_exec or system , or simply schedule a cronjob as suggested.

I particularly use cronjob from a remote system, which calls mysqldump , generating my daily backups there.

$ this-> dbutil-> backup ()

On one occasion, the boring provider server hosting the project application I was working on did not allow remote access to MySQL at all. I did not have SSH access. mysqldump was not an option. I did not have a phpMyAdmin of life to generate a dump .

So the previous developers had already done their PHP script, which made queries , from SHOW TABLES to everything else you could imagine, and mounted the corresponding SQL file containing the dump .

The problem is that it did not work. But nobody knew that. Apparently everything was going well. However, certain strings were truncated. I just "discovered" this because using my local version of the application, I suddenly noticed a slightly different content from the remote application. I was intrigued, and investigating came to the fact that the script did not work well enough to generate a faithful dump .

The solution I found was the % method of the Database Utility Class

14.02.2014 / 04:54
1
// aqui esta o script para tal função funcionando perfeitamente e testado
// exaustivamente em meu servidor; não inventei nada somente fiz a junção de
// uma parte de código que peguei aqui e uma outra parte de um outro lugar e // efetuei pequenas correções; Não necessita de mais nada além do código
// na tarefa CRON inclua php -q /home/usuariodosite/pasta aonde esta o script

<?php
// Backup do banco de dados do site

$dbhost = 'localhost';          //local aonde se encontra o banco de dados
$dbuser = '---';    // usuário do banco de dados
$dbpass = '---';         // senha do usuário do banco de dados
$dbname = '---';   // nome do banco de dados

// rotina que faz o backup não mexer

$backupfile = 'Autobackup_' . date("Ymd") . '.sql';
$backupzip = $backupfile . '.tar.gz';
system("mysqldump -h $dbhost -u $dbuser -p$dbpass --lock-tables $dbname > $backupfile");
system("tar -czvf $backupzip $backupfile");

// ROTINA DE ENVIO DO EMAIL COM O ANEXO 

$to = "---";         //Quem vai receber o email
$from = "---";  //Quem está enviando (Endereço a ser apresentado como da pessoa que está enviando)
$subject = 'Backup do Banco de Dados Sql ';          //Assunto do email
$messagem = 'cópia do backup do banco de dados Sql'; //Mensagem a ser enviada
$path = "---";                  //Diretório onde o arquivo a ser enviado está salvo
$filename = "$backupzip";                        //Nome do arquivo anexo a ser enviado - não mexer aqui

// ---------- Não altere nada deste ponto em diante ----------

$headers = 'From: ' .     "$from\r\n" . 'Reply-To: ' . "$from\r\n";

$file = $path . "/" . $filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));

$separator = md5(time());   // a random hash será necessário para separar conteúdos diversos a serem enviados
$eol = PHP_EOL;   // Define o retorno de carro a ser utilizado

// main header (multipart mandatory)
$headers = "From: < $from >" . $eol;
$headers .= "MIME-Version: 1.0" . $eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"" . $separator . "\"" . $eol . $eol;
$headers .= "Content-Transfer-Encoding: 7bit" . $eol;
$headers .= "This is a MIME encoded message." . $eol . $eol;

// messagem
$headers .= "--" . $separator . $eol;
$headers .= "Content-Type: text/plain; charset=\"utf-8\"" . $eol;
$headers .= "Content-Transfer-Encoding: 8bit" . $eol . $eol;
$headers .= $messagem . $eol . $eol;

// attachment
$headers .= "--" . $separator . $eol;
$headers .= "Content-Type: application/octet-stream; name=\"" . $filename . "\"" . $eol;
$headers .= "Content-Transfer-Encoding: base64" . $eol;
$headers .= "Content-Disposition: attachment" . $eol . $eol;
$headers .= $content . $eol . $eol;
$headers .= "--" . $separator . "--";

//SEND Mail

if (mail($to, $subject, "", $headers)) {
   echo "Sucesso no envio do Email";
} else {
   echo "Erro! Não foi possível enviar o email solicitado";
}

// Remover o arquivo do servidor (opcional)
unlink($backupzip);
unlink($backupfile);
?>
    
17.10.2016 / 04:14
0

Here is a complete and up-to-date tutorial to solve your need:

link

With it you can create a copy of the MySQL database automatically using a PHP file and a CRON task. The file is compressed with ZIP.

    
24.05.2018 / 18:36
-1

I do not know if this is what you need, but it follows a complete code to make bkp from your database, just save the code in a php file, create a folder called "db_bkp" and do not forget to fill in the data access to the database

<?php
ini_set('display_errors',1); ini_set('display_startup_erros',1); error_reporting(E_ALL);//force php to show any error message

backup_tables(DB_HOST,DB_USER,DB_PASS,DB_NAME);//don't forget to fill with your own database access informations

function backup_tables($host,$user,$pass,$name)
{
    $link = mysqli_connect($host,$user,$pass);
    mysqli_select_db($link, $name);
        $tables = array();
        $result = mysqli_query($link, 'SHOW TABLES');
        $i=0;
        while($row = mysqli_fetch_row($result))
        {
            $tables[$i] = $row[0];
            $i++;
        }
    $return = "";
    foreach($tables as $table)
    {
        $result = mysqli_query($link, 'SELECT * FROM '.$table);
        $num_fields = mysqli_num_fields($result);
        $return .= 'DROP TABLE IF EXISTS '.$table.';';
        $row2 = mysqli_fetch_row(mysqli_query($link, 'SHOW CREATE TABLE '.$table));
        $return.= "\n\n".$row2[1].";\n\n";
        for ($i = 0; $i < $num_fields; $i++)
        {
            while($row = mysqli_fetch_row($result))
            {
                $return.= 'INSERT INTO '.$table.' VALUES(';
                for($j=0; $j < $num_fields; $j++)
                {
                    $row[$j] = addslashes($row[$j]);
                    if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
                    if ($j < ($num_fields-1)) { $return.= ','; }
                }
                $return.= ");\n";
            }
        }
        $return.="\n\n\n";
    }
    //save file
    $handle = fopen('db_bkp/db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+');//Don' forget to create a folder to be saved, "db_bkp" in this case
    fwrite($handle, $return);
    fclose($handle);
    echo "bkp efetuado com sucesso";//Sucessfuly message
}
?>
    
11.08.2016 / 01:30