2012-07-26 6 views
7

Ho uno script PHP che viene passato i dettagli di connessione MySQL di un server remoto e voglio che esegua un comando mysqldump. Per fare questo sto usando la funzione php exec():mysqldump via PHP

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

quando il diritto password vengono passati ad esso, funzionerà assolutamente bene. Tuttavia, ho problemi a controllare se si esegue come previsto e se non viene rilevato perché no. L'array $output restituisce come vuoto, mentre se eseguo il comando direttamente sulla riga di comando viene stampato un messaggio che indica che l'accesso non è riuscito. Voglio catturare tali messaggi di errore e visualizzarli. Qualche idea su come farlo?

risposta

11

Si dovrebbe controllare il terzo parametro di exec funzione: &$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); 

Per convenzione in Unix un processo restituisce qualcosa di diverso da 0 quando qualcosa va storto.

e così si può:

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

ecco il link: http://php.net/manual/en/function.exec.php e penso sia meglio dirlo in questo modo: "Per convenzione in Unix un processo restituisce qualcosa di diverso da 0 quando qualcosa va storto" :) –

+0

Esiste un modo per sapere qual è il valore di ogni valore restituito da $ return_var in modo da poterlo tradurre in un messaggio di errore significativo? Suppongo che sia diverso per ogni comando. –

+0

se $ return_var non è uguale a zero, l'output $ deve avere il codice di errore, perché i programmi scrivono un errore su stderr che è diverso dallo stdout che hai reindirizzato a un file. 'if ($ return_var) {die ($ output); } ' –

4

Poiché questa linea di reindirizzare l'uscita stdout > /path-to-export/file.sql provare questo,

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

un po 'esagerato, se mi chiedete –

+0

La mia lingua madre è il turco, che è lontano da inglese, è questo che mi impedisce di scrivere le risposte potenti. Come lui dice che l'output $ è vuoto, allora ho detto il motivo per cui è vuoto. $ output è stdout e se usa ">" (che significa redirect stdout su file) non avrà output, e questo è assolutamente logico. Tuttavia c'è anche stderr, se c'è un errore $ output errore in questo caso, anche lui ha reindirizzato lo stdout al file. post scriptum ha chiesto $ output –

+0

sì sono completamente d'accordo, volevo solo dire che c'è un modo più semplice per farlo :) –

3

che stavo cercando la stessa soluzione esatta, e mi sono ricordato che avevo già risolto questo un paio di anni fa, ma dimenticato.

Poiché questa pagina è alto in Google per la domanda, ecco come ho fatto:

<?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"; 
} 
?> 

E 'il --log-error = [/ path/to/error/log/file] parte di mysqldump che dimentico sempre!

+0

Ho provato questa risposta ma non ho potuto farlo funzionare. Sto eseguendo un server WAMP locale e la directory in cui sto eseguendo è 'www/test/index.php'. Ho impostato 'BACKUP_PATH' su"/test/"e ho creato un file chiamato" mysqlydump_error.log "e l'ho inserito nella directory" test ". Ricevo il messaggio di errore, ma non visualizza un errore e anche il registro degli errori è vuoto. Mi sono assicurato che anche il mio utente abbia i permessi. Aiuto? –

+0

Ora posso visualizzare un file di backup, ma è vuoto. –

+0

@AndrewFox, [Rick] (http://stackoverflow.com/users/4392819/rick) dice "Il percorso non dovrebbe essere/www/test/o forse/var/www/test/a seconda della configurazione? Fai un pwd dalla directory in cui vuoi inserire il file di log e inseriscilo con una barra finale. ' –

3

La soluzione che ho trovato è di eseguire il comando in una sottostruttura e quindi di inviare stderr a stdout. In questo modo, lo $output è ben popolato.

vale a dire:

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

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

L'output:

int(6)

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

Speranza che aiuta!

1

Poiché exec() sta recuperando solo stdout che viene reindirizzato al file, abbiamo il risultato parziale o mancante nel file e non sappiamo perché. Dobbiamo ottenere un messaggio da stderr e exec() non possiamo farlo. Ci sono diverse soluzioni, tutto è già stato trovato quindi questo è solo un riassunto.

  1. Solution from Jon: registrare gli errori da mysqldump e gestirli separatamente (non può applicarsi per ogni comando).
  2. Reindirizza le uscite per separare i file, ad es.mysqldump ... 2> error.log 1> dump.sql e leggere il log degli errori separatamente come nella soluzione precedente.
  3. Solution from JazZ: scrivi il dump come una subshell e reindirizza lo stderr della subshell su stdout che può immettere nella variabile $output.
  4. Solution from Pascal: meglio utilizzare proc_open() anziché exec() perché è possibile ottenere stdout e stderr separatamente (direttamente dai tubi).
0

scrivere sotto il codice per ottenere l'esportazione del database nel file .sql.

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