Usando um arquivo .php para gerar um despejo MySQL

118

Aqui estão as informações que tenho:

Estou trabalhando com um sistema baseado em Linux usando MySQL e PHP5. Preciso ser capaz de gerar um mysqldumpde dentro de um arquivo .php e, em seguida, ter esse despejo armazenado em um arquivo no servidor em um local que eu especificaria.

Como sou um novato em PHP, gostaria que alguém me desse alguma assistência, orientação ou código, que faria o que eu solicito. Isso teria que ser executado remotamente a partir da Internet.

Thomas Ward
fonte
2
Verifique isso . Eu usaria mysqldumppor system().
dave
Este ajuda a criar o mysqldump com a ajuda de um arquivo php. kvcodes.com/2017/10/php-create-mysql-backup
Kvvaradha
Não confie em exec () ou system (), porque na maioria das vezes eles estão desabilitados em hospedagens compartilhadas. A resposta deve implementar uma maneira adequada de gerar um despejo de banco de dados sem executar programas externos.
diego

Respostas:

159

Você pode usar a exec()função para executar um comando externo.

Nota: entre shell_exec()e exec(), eu escolheria o segundo, que não retorna a saída para o script PHP - não há necessidade do script PHP para obter todo o dump SQL como uma string: você só precisa dele escrito em um arquivo, e isso pode ser feito pelo próprio comando.


Esse comando externo irá:

  • ser uma chamada para mysqldump, com os parâmetros certos,
  • e redirecionar a saída para um arquivo.

Por exemplo :

mysqldump --user=... --password=... --host=... DB_NAME > /path/to/output/file.sql


O que significa que seu código PHP seria assim:

exec('mysqldump --user=... --password=... --host=... DB_NAME > /path/to/output/file.sql');


Claro, depende de você usar as informações de conexão corretas, substituindo o ...por aqueles.

Pascal MARTIN
fonte
2
Vou tentar fazer isso em breve. Existe alguma maneira de gerar saída na página PHP quando ela for concluída, dizendo "Dump complete!" ou alguma coisa?
Thomas Ward
6
exec()não retornará até que o comando seja concluído; então, basta colocar um pouco echo "dump complete"depois de ligarexec()
Pascal MARTIN
7
Isso me ajudou hoje - e uma observação para os usuários do osx lion: o atalho do mysqldump não foi configurado para mim quando instalei o mysql, então eu tive que encontrá-lo - aqui está o caminho:/usr/local/mysql/bin/mysqldump
totallyNotLizards
4
Seu comentário, jammypeach, salvou minha vida. Observe que any1 pode precisar desta pequena adição: '/ usr / local / mysql / bin / mysqldump -u ...'
helpse
1
Nota para usuários do Windows: No Windows, você deve especificar o caminho completo para mysqldump.exe, por exemploexec("C:/pathto/mysql/bin/mysqldump.exe <options as above>");
pogosama
83

Se você deseja criar um backup para baixá-lo através do navegador, você também pode fazer isso sem usar um arquivo.

A função php passthru () redirecionará diretamente a saída do mysqldump para o navegador. Neste exemplo, ele também será compactado.

Pro: você não precisa lidar com arquivos temporários.

Con: Não funciona no Windows. Pode ter limites com grandes conjuntos de dados.

<?php

$DBUSER="user";
$DBPASSWD="password";
$DATABASE="user_db";

$filename = "backup-" . date("d-m-Y") . ".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";   

passthru( $cmd );

exit(0);
?>
MajorLeo
fonte
25

Dê uma olhada aqui: https://github.com/ifsnop/mysqldump-php ! É uma solução nativa escrita em php.

Você pode instalá-lo usando o composer, e é tão fácil quanto fazer:

<?php

use Ifsnop\Mysqldump as IMysqldump;

try {
    $dump = new IMysqldump\Mysqldump('database', 'username', 'password');
    $dump->start('storage/work/dump.sql');
} catch (\Exception $e) {
    echo 'mysqldump-php error: ' . $e->getMessage();
}

?>

Ele suporta usuários avançados, com muitas opções copiadas do mysqldump original.

Todas as opções são explicadas na página do github, mas mais ou menos são auto-explicativas:

$dumpSettingsDefault = array(
    'include-tables' => array(),
    'exclude-tables' => array(),
    'compress' => 'None',
    'no-data' => false,
    'add-drop-database' => false,
    'add-drop-table' => false,
    'single-transaction' => true,
    'lock-tables' => false,
    'add-locks' => true,
    'extended-insert' => true,
    'disable-foreign-keys-check' => false,
    'where' => '',
    'no-create-info' => false
);
diego
fonte
2
Mesmo em servidores que foram exece / ou shell_execdesabilitados por segurança, mysqldump-php funciona muito bem! Apenas tentei agora nos servidores do Umbler e consegui o despejo com sucesso. Muito obrigado pela dica!
giovannipds
isso é perfeito para servidores que não têm comandos do shell mysql disponíveis também!
Andrej
9

Consulte o seguinte link que contém um scriptlet que o ajudará: http://davidwalsh.name/backup-mysql-database-php

Nota: Este script pode conter bugs com tipos de dados NULL

André Puel
fonte
Obrigado, este é um plano B útil se "shell_exec () foi desativado por razões de segurança" (aí está, Google)
Deebster
1
Observe que este usa comandos mysql obsoletos em vez de mysqli.
Pascal Raszyk
"Bugs com tipos de dados NULL" soa como um problema para uma solução de backup.
alexis
7

Por razões de segurança, é recomendado especificar a senha em um arquivo de configuração e não no comando (um usuário pode executar um ps aux | grep mysqldumpe ver a senha).

//create a temporary file
$file   = tempnam(sys_get_temp_dir(), 'mysqldump');

//store the configuration options
file_put_contents($file, "[mysqldump]
user={$user}
password=\"{$password}\"");

//execute the command and output the result
passthru("mysqldump --defaults-file=$file {$dbname}");

//delete the temporary file
unlink($file);
Constantin Galbenu
fonte
5

Aqui você pode encontrar uma solução abrangente para descartar a estrutura do mysql e dados como no PMA (e sem usar exec, passthru etc.):

https://github.com/antarasi/MySQL-Dump-with-Foreign-keys

É a bifurcação do projeto dszymczuk com minhas melhorias.

O uso é simples

<?php
//MySQL connection parameters
$dbhost = 'localhost';
$dbuser = 'dbuser';
$dbpsw = 'pass';
$dbname = 'dbname';

//Connects to mysql server
$connessione = @mysql_connect($dbhost,$dbuser,$dbpsw);

//Set encoding
mysql_query("SET CHARSET utf8");
mysql_query("SET NAMES 'utf8' COLLATE 'utf8_general_ci'");

//Includes class
require_once('FKMySQLDump.php');


//Creates a new instance of FKMySQLDump: it exports without compress and base-16 file
$dumper = new FKMySQLDump($dbname,'fk_dump.sql',false,false);

$params = array(
    //'skip_structure' => TRUE,
    //'skip_data' => TRUE,
);

//Make dump
$dumper->doFKDump($params);

?>

Funciona como um encanto :-)

ANTARA
fonte
Ele funciona - mas produz uma saída diferente do mysqldump PHPMYADMIN. Por quê ? Há dados faltando, enquanto meu backup PHPMYADMIN é concluído.
ledawg
@ Ledew-de: Os dados não devem ser incluídos no dump apenas se a opção skip_data => true for passada como um parâmetro
ANTARA
3

Contanto que você tenha permissão para usar exec () , você pode executar comandos shell por meio de seu código PHP.

Supondo que você saiba como escrever o mysqldump na linha de comando, ou seja,

mysqldump -u [username] -p [database] > [database].sql

então você pode usar isso como o parâmetro para a função exec ().

exec("mysqldump -u mysqluser -p my_database > my_database_dump.sql");
Charliefortune
fonte
3

A resposta do MajorLeo me apontou na direção certa, mas não funcionou para mim. Encontrei este site que segue a mesma abordagem e funcionou.

$dir = "path/to/file/";
$filename = "backup" . date("YmdHis") . ".sql.gz";

$db_host = "host";
$db_username = "username";
$db_password = "password";
$db_database = "database";

$cmd = "mysqldump -h {$db_host} -u {$db_username} --password={$db_password} {$db_database} | gzip > {$dir}{$filename}";
exec($cmd);

header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$filename\"");

passthru("cat {$dir}{$filename}");

Espero que ajude mais alguém!

Matías Cánepa
fonte
O seu aqui retorna a saída para o usuário final, não é? IE após a execução, ele exibe de uma forma que você poderia copiar / colar? Se sim, então isso não alcançaria o que a resposta aceita - apenas cria o arquivo no servidor para que eu pudesse pegá-lo por scp.
Thomas Ward
@ThomasW. Este código faz duas coisas: ele gera um arquivo salvo no servidor e exibe a caixa de diálogo de download. Se você deseja apenas armazenar o arquivo, não faça a parte do cabeçalho () e do passthru (). E se você precisar apenas da localização do arquivo, você sempre pode ecoar as variáveis ​​$ dir & $ filename .... Não importa o que você escolha, você ainda pode acessar o arquivo via SCP
Matías Cánepa
0

<?php exec('mysqldump --all-databases > /your/path/to/test.sql'); ?>

Você pode estender o comando com qualquer opção do mysqldump, é claro. Use man mysqldumppara mais opções (mas acho que você sabia disso;))

Rem.co
fonte
0

global $wpdb;
$export_posts = $wpdb->prefix . 'export_posts';
$backupFile = $_GET['targetDir'].'export-gallery.sql';
$dbhost=DB_HOST;
$dbuser=DB_USER;
$dbpass=DB_PASSWORD;
$db=DB_NAME;
$path_to_mysqldump = "D:\xampp_5.6\mysql\bin";
$query= "D:\\xampp_5.6\mysql\bin\mysqldump.exe -u$dbuser -p$dbpass $db $export_posts> $backupFile";
exec($query);
echo $query;

Fuad Hasan
fonte
0

Nenhum dos códigos acima funcionou para mim. Estou usando o windows. O código abaixo funcionou para mim ...

$sql = "SELECT * FROM  $tableName WHERE yourclause";
$result = $conn->query($sql);


if($result){

        if ($result->num_rows > 0) {

            $myfile = fopen("daily_events_$district.sql", "w") or die("Unable to open file!");

            while($row = $result->fetch_assoc()) {  

                $rowToString = implode("','",$row);
                $writeToFile = "INSERT INTO $tableName VALUES('$rowToString');". PHP_EOL;
                fwrite($myfile,$writeToFile);
            }
            echo "File saved successfully";
        }
    } else {
        echo "No result found";
    }

Isso salvará o arquivo na pasta do seu projeto de acordo com a sua consulta, quaisquer dados que você deseja.

Swarnim Dixit
fonte
Esta solução é essencialmente falha, pois cria strings SQL incorretas
Seu senso comum
-1

Para despejar o banco de dados usando shell_exec (), a seguir está o método:

shell_exec('mysqldump -h localhost -u username -ppassword databasename  | gzip > dbname.sql.gz');
Digisha
fonte
-2
<?php
    $toDay = date('d-m-Y');

    $dbhost =   "localhost";
    $dbuser =   "YOUR DB USER";
    $dbpass =   "USER PASSWORD";
    $dbname =   "DB NAME";

    exec("mysqldump --user=$dbuser --password='$dbpass' --host=$dbhost $dbname > /home/....../public_html/".$toDay."_DB.sql");


?>
PradeepJangid
fonte