2012-07-26 53 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'); ?>