使用.php文件生成MySQL转储文件

136

以下是我所了解的信息:

我正在使用基于Linux系统的MySQL和PHP5。我需要能够从.php文件中生成一个mysqldump,然后将该转储存储在服务器上我指定的位置的文件中。

由于我是PHP新手,希望有人能给我提供一些协助、指导或代码,以完成我的需求。这需要在互联网上远程运行。


2
查看此链接。我会使用system()通过mysqldump进行备份。 - dave
这个可以帮助使用 PHP 文件创建 mysqldump。http://www.kvcodes.com/2017/10/php-create-mysql-backup/ - Kvvaradha
不要依赖于exec()或system(),因为它们在共享主机上大多数时候都被禁用了。答案应该实现一种适当的方式来生成数据库转储,而不运行外部程序。 - diego
13个回答

175

你可以使用 exec() 函数来执行外部命令。

注意:在 shell_exec()exec() 之间,我会选择后者,因为它不会将输出返回给PHP脚本 - 没有必要让PHP脚本得到整个SQL转储字符串:你只需要将其写入文件即可,而这可以通过命令本身完成。


那个外部命令将会:

  • 调用带有正确参数的mysqldump
  • 并将输出重定向到一个文件。

例如:

mysqldump --user=... --password=... --host=... DB_NAME > /path/to/output/file.sql
这意味着你的PHP代码将会是这样的:
exec('mysqldump --user=... --password=... --host=... DB_NAME > /path/to/output/file.sql');


当然,使用正确的连接信息取决于您自己,将...替换为相应的信息即可。


为了使它起作用,我不得不将 mysqldump 替换为 /usr/bin/mysqldump。我还必须将 password=mystrongpassword 更改为 password="mystrongpassword" - ban-geoengineering

95

如果您想通过浏览器创建备份并下载它,也可以不使用文件来完成此操作。

PHP函数 passthru()将直接将mysqldump的输出重定向到浏览器。在本示例中,它还将被压缩。

优点:您无需处理临时文件。

缺点:在Windows上无法使用。可能会限制大型数据集。

<?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);
?>

1
安全问题:命令“mysqldump ....”是否存储在系统中?我考虑到其中包含了明文密码。 - Eugenio

35

看这里:https://github.com/ifsnop/mysqldump-php! 这是用PHP编写的本地解决方案。

您可以使用composer安装它,方法就像这样简单:

<?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();
}

?>

它支持高级用户,有很多从原始mysqldump复制的选项。

所有选项都在github页面上解释,但更多或少自动解释。

$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
);

这个脚本的最大优势是可以在A服务器上由PHP运行,而数据库在B服务器上。被认可的答案更简单,但只有当PHP脚本和数据库都在同一台服务器上时才有效。 - spiritoo

9

出于安全原因,建议在配置文件中指定密码,而不是在命令行中指定(用户可以执行 ps aux | grep mysqldump 命令并查看密码)。

//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);

6
在这里,您可以找到一种综合解决方案,以类似于PMA的方式转储mysql结构和数据(而且不使用exec、passthru等)。

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

这是dszymczuk项目的分支,并加入了我的改进。
使用方法很简单。
<?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);

?>

运行得非常好 :-)


它确实可以工作,但产生的输出与PHPMYADMIN mysqldump不同。为什么?有数据丢失,而我的PHPMYADMIN备份是完整的。 - ledawg
@Ledew-de:如果传递了skip_data=>true选项作为参数,则dump中不应包含数据。 - ANTARA
如果有人仍然对这个解决方案感兴趣,我已经fork了这个项目,修复了很多bug,并使其与PHP 8.1兼容:https://github.com/danielmarschall/MySQL-Dump-with-Foreign-keys - Daniel Marschall

5

MajorLeo的回答让我找到了正确的方向,但对我没有起作用。 我找到了这个网站,它采用相同的方法并且有效。

$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}");

我希望这能帮助到其他人!


你的代码会将输出返回给最终用户,是吗?也就是说,在执行时,它会以一种可以复制/粘贴的方式输出吗?如果是这样,那么这并不能达到接受答案的效果 - 它只是在服务器上创建文件,以便我可以通过scp获取它。 - Thomas Ward
@ThomasW。这段代码有两个作用:它生成一个保存在服务器上的文件并提示下载对话框。如果您只想存储文件,则不要执行header()和passthru()部分。如果您需要文件位置,您可以随时echo $dir&$filename变量....无论您选择什么,您仍然可以通过SCP访问该文件。 - Matías Cánepa

3
只要允许使用exec(),您就可以通过PHP代码执行shell命令。
因此,假设您知道如何在命令行中编写mysqldump,即:
mysqldump -u [username] -p [database] > [database].sql

然后您可以将此作为exec()函数的参数使用。
exec("mysqldump -u mysqluser -p my_database > my_database_dump.sql");

这将创建一个密码提示。我如何通过 PHP 脚本对此密码提示作出反应?exec("mystrongpw"); 将不起作用。 - emma

0

0

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

你可以添加任何mysqldump支持的选项来扩展该命令。使用man mysqldump获取更多选项(但我猜你已经知道了;))


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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接