Użycie pliku .php do wygenerowania zrzutu MySQL


118

Oto informacje, które mam:

Pracuję z systemem opartym na Linuksie przy użyciu MySQL i PHP5. Muszę mieć możliwość wygenerowania pliku mysqldumpz pliku .php, a następnie zapisania tego zrzutu w pliku na serwerze w określonej przeze mnie lokalizacji.

Ponieważ jestem noobletem PHP, chciałbym, aby ktoś udzielił mi pomocy, wskazówek lub kodu, który zrobiłby to, czego potrzebuję. Musiałoby to być uruchamiane zdalnie z Internetu.


2
Sprawdź to . Użyłbym mysqldumpprzez system().
dave,


Ten pomaga stworzyć mysqldump z pomocą pliku php. kvcodes.com/2017/10/php-create-mysql-backup
Kvvaradha

Nie polegaj na exec () lub system (), ponieważ w większości przypadków są one wyłączone na współdzielonych hostach. Odpowiedź powinna implementować prawidłowy sposób generowania zrzutu bazy danych bez uruchamiania programów zewnętrznych.
diego

Odpowiedzi:


159

Możesz użyć tej exec()funkcji do wykonania zewnętrznego polecenia.

Uwaga: między shell_exec()a exec()wybrałbym drugi, który nie zwraca danych wyjściowych do skryptu PHP - nie ma potrzeby, aby skrypt PHP pobierał cały zrzut SQL jako ciąg znaków: wystarczy, że zostanie on zapisany do pliku, i można to zrobić za pomocą samego polecenia.


To zewnętrzne polecenie:

  • być wezwaniem mysqldump, z odpowiednimi parametrami,
  • i przekieruj dane wyjściowe do pliku.

Na przykład :

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


Co oznacza, że ​​Twój kod PHP wyglądałby tak:

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


Oczywiście do Ciebie należy użycie odpowiednich informacji o połączeniu, zastępując ...te.


2
Wkrótce się tym zajmę. Czy istnieje sposób na wygenerowanie danych wyjściowych na stronie PHP po jej zakończeniu mówiąc „Zrzut zakończony!” lub coś?
Thomas Ward,

6
exec()nie zwróci, dopóki polecenie nie zostanie zakończone; więc po prostu włóż trochę echo "dump complete"po zadzwonieniuexec()
Pascal MARTIN

7
Pomogło mi to dzisiaj - i uwaga dla użytkowników osx lion: mysqldump skrót nie został skonfigurowany, kiedy instalowałem mysql, więc musiałem go znaleźć - oto ścieżka:/usr/local/mysql/bin/mysqldump
totalNotLizards

4
Twój komentarz, jammypeach, uratował mi życie. Zwróć uwagę, że any1 może potrzebować tego małego dodatku: '/ usr / local / mysql / bin / mysqldump -u ...'
helpse

1
Uwaga dla użytkowników systemu Windows: W systemie Windows należy podać pełną ścieżkę do mysqldump.exe, np.exec("C:/pathto/mysql/bin/mysqldump.exe <options as above>");
pogosama

83

Jeśli chcesz utworzyć kopię zapasową, aby pobrać ją przez przeglądarkę, możesz to również zrobić bez użycia pliku.

Funkcja php passthru () bezpośrednio przekieruje wyjście mysqldump do przeglądarki. W tym przykładzie również zostanie spakowany.

Pro: Nie musisz zajmować się plikami tymczasowymi.

Wada: nie będzie działać w systemie Windows. Może mieć ograniczenia w przypadku ogromnych zbiorów danych.

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

25

Spójrz tutaj: https://github.com/ifsnop/mysqldump-php ! Jest to natywne rozwiązanie napisane w php.

Możesz go zainstalować za pomocą narzędzia Composer i jest to tak proste, jak:

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

?>

Obsługuje zaawansowanych użytkowników, z wieloma opcjami skopiowanymi z oryginalnego mysqldump.

Wszystkie opcje są wyjaśnione na stronie github, ale mniej więcej są auto-wyjaśniające:

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

2
Nawet na serwerach, które mają execi / lub są shell_execwyłączone przez zabezpieczenia, mysqldump-php działa świetnie! Właśnie wypróbowałem to teraz na serwerach Umblera i pomyślnie wykonałem zrzut. Bardzo dziękuję za wskazówkę!
giovannipds

jest to idealne rozwiązanie dla serwerów, które nie mają również dostępnych poleceń powłoki mysql!
Andrej

9

Skieruj się na poniższy link, który zawiera skryptlet, który pomoże Ci: http://davidwalsh.name/backup-mysql-database-php

Uwaga: ten skrypt może zawierać błędy z typami danych NULL


Dzięki, to przydatny plan B, jeśli „shell_exec () został wyłączony ze względów bezpieczeństwa” (proszę bardzo, Google)
Deebster,

1
Zwróć uwagę, że używa to przestarzałych poleceń mysql zamiast mysqli.
Pascal Raszyk

„Błędy z typami danych NULL” brzmią jak problem z rozwiązaniem do tworzenia kopii zapasowych.
Alexis

7

Ze względów bezpieczeństwa zaleca się podanie hasła w pliku konfiguracyjnym, a nie w poleceniu (użytkownik może wykonać a ps aux | grep mysqldumpi zobaczyć hasło).

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

5

Tutaj znajdziesz kompleksowe rozwiązanie do zrzucania struktury i danych mysql, takich jak w PMA (bez użycia exec, passthru itp.):

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

To rozwidlenie projektu dszymczuk z moimi ulepszeniami.

Użycie jest proste

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

?>

działa jak marzenie :-)


Działa - ale generuje inny wynik niż mysqldump PHPMYADMIN. Czemu ? Brakuje danych, a moja kopia zapasowa PHPMYADMIN jest zakończona.
ledawg

@ Ledew-de: Dane nie powinny być uwzględniane w zrzucie tylko wtedy, gdy opcja skip_data => true jest przekazana jako parametr
ANTARA

3

Dopóki możesz używać funkcji exec () , możesz wykonywać polecenia powłoki za pośrednictwem kodu PHP.

Zakładając, że wiesz, jak napisać mysqldump w linii poleceń, tj

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

możesz użyć tego jako parametru funkcji exec ().

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

3

Odpowiedź MajorLeo wskazuje mi właściwy kierunek, ale nie zadziałała. Znalazłem tę witrynę, która stosuje to samo podejście i działa.

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

Mam nadzieję, że pomoże to komuś innemu!


Twój tutaj zwraca dane wyjściowe do użytkownika końcowego, prawda? IE po wykonaniu wyświetla go w sposób, w jaki można skopiować / wkleić? Jeśli tak, to nie przyniosłoby to tego, co zrobiła zaakceptowana odpowiedź - po prostu tworzy plik na serwerze, aby móc go pobrać przez scp.
Thomas Ward

@ThomasW. Ten kod robi dwie rzeczy: generuje plik zapisany na serwerze i wyświetla okno dialogowe pobierania. Jeśli chcesz tylko zapisać plik, nie wykonuj części header () i passthru (). A jeśli potrzebujesz tylko lokalizacji pliku, zawsze możesz powtórzyć zmienne $ dir i $ filename .... Bez względu na to, co wybierzesz, nadal możesz uzyskać dostęp do pliku przez SCP
Matías Cánepa


0

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

Możesz rozszerzyć polecenie o dowolne opcje, które mysqldump bierze oczywiście. Użyj, man mysqldumpaby uzyskać więcej opcji (ale myślę, że wiesz o tym;))



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;


0

Żaden z powyższych kodów nie działał dla mnie. Używam Windows. Poniższy kod zadziałał dla mnie ...

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

Spowoduje to zapisanie pliku w folderze projektu zgodnie z zapytaniem, dowolne dane.


To rozwiązanie jest zasadniczo wadliwe, ponieważ tworzy niepoprawne ciągi SQL
Your Common Sense

-1

Aby zrzucić bazę danych za pomocą shell_exec (), poniżej znajduje się metoda:

shell_exec('mysqldump -h localhost -u username -ppassword databasename  | gzip > dbname.sql.gz');

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


?>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.