2012-07-26 57 views
7

我有一个PHP脚本,通过远程服务器的MySQL连接细节,我希望它执行mysqldump命令。要做到这一点,我使用PHP exec()功能:mysqldump通过PHP

<?php 
exec("/usr/bin/mysqldump -u mysql-user -h 123.145.167.189 -pmysql-pass database_name > /path-to-export/file.sql", $output); 
?> 

当正确的登录信息传递给它,它会工作精绝。 但是,如果按预期执行,并且未找到原因,我在检查时遇到问题。 $output数组返回为空,而如果我直接在命令行上运行该命令,则会打印出一条消息,告诉我登录失败。我想捕获这些错误信息并显示它们。任何想法如何做到这一点?

回答

11

您应该检查的EXEC函数的第三个参数:&$return_var

$return_var = NULL; 
$output = NULL; 
$command = "/usr/bin/mysqldump -u mysql-user -h 123.145.167.189 -pmysql-pass database_name > /path-to-export/file.sql"; 
exec($command, $output, $return_var); 

通过Unix约定一个过程出问题的时候返回0以外的任何东西。

所以你可以:

if($return_var) { /* there was an error code: $return_var, see the $output */ } 
+1

这里是链接:http://php.net/manual/en/function.exec.php,我认为最好这样说:“按照Unix惯例,当出现错误时,进程返回0以外的任何值” :) – 2012-07-26 23:17:12

+0

有没有什么办法可以知道$ return_var的每个值是什么意思,所以我可以将它翻译成一个有意义的错误信息?会猜测每个命令都不一样。 – 2012-07-26 23:35:46

+0

如果$ return_var不等于零,$输出必须有错误代码,因为程序将错误写入stderr,而stderr与您重定向到文件的stdout不同。 'if($ return_var){die($ output); }' – 2012-07-27 02:18:08

4

因为该行重定向标准输出输出> /path-to-export/file.sql 试试这个,

<?php 
exec("/usr/bin/mysqldump -u mysql-user -h 123.145.167.189 -pmysql-pass database_name", $output); 
/* $output will have sql backup, then save file with these codes */ 
$h=fopen("/path-to-export/file.sql", "w+"); 
fputs($h, $output); 
fclose($h); 
?> 
+0

有点牵强如果你问我 – 2012-07-26 23:19:32

+0

我的母语是土耳其语,它远离英语,这就是阻止我写出有力答案的原因。正如他所说的$输出是空的,那么我说为什么它是空的原因。 $ output是stdout,如果他使用“>”(这意味着将stdout重定向到文件),他将不会有输出,这是完全合乎逻辑的。但也有stderr,如果在这种情况下出现$ output错误,即使他将stdout重定向到文件。附:他问$输出 – 2012-07-26 23:25:35

+0

是的,我完全同意,我的意思是有一个更简单的方法来做到这一点:) – 2012-07-26 23:29:03

3

我一直在寻找完全相同的解决方案,我记得我已经解决了这个几年前,但忘记了。

由于这页是高在谷歌的问题,这里是我是如何做到的:

<?php 
define("BACKUP_PATH", "/full/path/to/backup/folder/with/trailing/slash/"); 

$server_name = "your.server.here"; 
$username  = "your_username"; 
$password  = "your_password"; 
$database_name = "your_database_name"; 
$date_string = date("Ymd"); 

$cmd = "mysqldump --hex-blob --routines --skip-lock-tables --log-error=mysqldump_error.log -h {$server_name} -u {$username} -p{$password} {$database_name} > " . BACKUP_PATH . "{$date_string}_{$database_name}.sql"; 

$arr_out = array(); 
unset($return); 

exec($cmd, $arr_out, $return); 

if($return !== 0) { 
    echo "mysqldump for {$server_name} : {$database_name} failed with a return code of {$return}\n\n"; 
    echo "Error message was:\n"; 
    $file = escapeshellarg("mysqldump_error.log"); 
    $message = `tail -n 1 $file`; 
    echo "- $message\n\n"; 
} 
?> 

这是--log错误= [/路径/到/错误/日志/文件]我总是忘记的mysqldump的一部分!

+0

我试过这个答案,但不能得到它的工作。我运行的是本地WAMP服务器,我运行的目录是'www/test/index.php'。我已将'BACKUP_PATH'设置为“/ test /”,并创建了一个名为“mysqlydump_error.log”的文件,并将其放在“test”目录中。我收到错误消息,但它不显示错误,错误日志也是空的。我确定我的用户也有权限。帮帮我? – 2014-12-24 07:08:14

+0

现在我可以得到一个备份文件出现,但它是空白的。 – 2014-12-24 07:37:20

+0

@AndrewFox,[Rick](http://stackoverflow.com/users/4392819/rick)说'不应该路径/ www/test /或可能/ var/www/test /取决于您的配置?从你想放置日志文件的目录中做一个pwd,并把它放在尾部的斜杠上。' – 2014-12-25 01:36:08

3

我找到的解决方案是在子shell中运行命令,然后输出stderrstdout。这样,$output填充得很好。

即:

exec("(mysqldump -u$username -p$password $database $tables > $dump_name) 2>&1", $output, $result); 

var_dump($result); 
echo "<br />"; 
var_dump($output); 
echo "<br />"; 

输出:

int(6)

array(1) { [0]=> string(46) "mysqldump: Couldn't find table: "table_name"" }

希望它能帮助!

1

由于exec()正在提取stdout这是重定向到文件,我们有部分或缺失的结果在文件中,我们不知道为什么。我们必须从stderrexec()得到消息不能这样做。有几种解决方案,都已经找到了,所以这只是一个总结。

  1. Solution from Jon:从mysqldump记录错误,并分别处理它们(不能申请的每一个命令)。
  2. 将输出重定向到单独的文件,即mysqldump ... 2> error.log 1> dump.sql并单独读取错误日志,如以前的解决方案。
  3. Solution from JazZ:将转储写入子shell并将子shell的stderr重定向到标准输出,其中php exec()将置于$output变量中。
  4. Solution from Pascal:最好使用proc_open()而不是exec(),因为我们可以分别得到stdoutstderr(直接来自管道)。
0

写下面的代码来获取数据库导出到.sql文件。

<?php exec('mysqldump --user=name_user --password=password_enter --host=localhost database_name > filenameofsql.sql'); ?>