Utilisation d'un fichier .php pour générer un vidage MySQL

118

Voici les informations dont je dispose:

Je travaille avec un système basé sur Linux utilisant MySQL et PHP5. Je dois être en mesure de générer un mysqldumpfichier à partir d'un fichier .php, puis de stocker ce vidage dans un fichier sur le serveur à un emplacement que je spécifierais.

Comme je suis un nooblet PHP, j'aimerais que quelqu'un me donne de l'aide, des conseils ou du code, qui ferait ce dont j'ai besoin. Cela devrait être exécuté à distance depuis Internet.

Thomas Ward
la source
2
Vérifiez ceci . J'utiliserais mysqldumppar system().
dave
Celui-ci aide à créer mysqldump avec l'aide d'un fichier php. kvcodes.com/2017/10/php-create-mysql-backup
Kvvaradha
Ne comptez pas sur exec () ou system (), car la plupart du temps, ils sont désactivés sur les hébergements partagés. La réponse doit implémenter une manière appropriée de générer un vidage de base de données sans exécuter de programmes externes.
diego

Réponses:

159

Vous pouvez utiliser le exec() fonction pour exécuter une commande externe.

Remarque: entre shell_exec() et exec(), je choisirais le second, qui ne renvoie pas la sortie au script PHP - pas besoin du script PHP pour obtenir le vidage SQL complet sous forme de chaîne: vous n'avez besoin que de l'écrire dans un fichier, et cela peut être fait par la commande elle-même.


Cette commande externe:

  • être un appel à mysqldump , avec les bons paramètres,
  • et redirigez la sortie vers un fichier.

Par exemple :

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


Ce qui signifie que votre code PHP ressemblerait à ceci:

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


Bien sûr, à vous d'utiliser les bonnes informations de connexion, en les remplaçant ...par celles-ci.

Pascal MARTIN
la source
2
Je vais essayer de le faire sous peu. Existe-t-il un moyen de générer une sortie sur la page PHP lorsqu'elle a terminé en disant "Dump terminé!" ou quelque chose?
Thomas Ward
6
exec()ne reviendra pas tant que la commande ne sera pas terminée; donc, il suffit d'en mettre echo "dump complete"après avoir appeléexec()
Pascal MARTIN
7
Cela m'a aidé aujourd'hui - et une note pour les utilisateurs d'osx lion: le raccourci mysqldump n'a pas été configuré pour moi lorsque j'ai installé mysql, donc j'ai dû le trouver - voici le chemin:/usr/local/mysql/bin/mysqldump
totalementNotLizards
4
Votre commentaire, jammypeach, m'a sauvé la vie. Veuillez noter que any1 pourrait avoir besoin de ce petit ajout: '/ usr / local / mysql / bin / mysqldump -u ...'
helpse
1
Remarque pour les utilisateurs de Windows: sous Windows, vous devez spécifier le chemin complet de mysqldump.exe, par exempleexec("C:/pathto/mysql/bin/mysqldump.exe <options as above>");
pogosama
83

Si vous souhaitez créer une sauvegarde pour la télécharger via le navigateur, vous pouvez également le faire sans utiliser de fichier.

La fonction php passthru () redirigera directement la sortie de mysqldump vers le navigateur. Dans cet exemple, il sera également compressé.

Pro: Vous n'avez pas à gérer les fichiers temporaires.

Con: ne fonctionnera pas sous Windows. Peut avoir des limites avec d'énormes ensembles de données.

<?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);
?>
MajorLeo
la source
25

Jetez un œil ici: https://github.com/ifsnop/mysqldump-php ! C'est une solution native écrite en php.

Vous pouvez l'installer à l'aide de composer, et c'est aussi simple que de le faire:

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

?>

Il prend en charge les utilisateurs avancés, avec de nombreuses options copiées à partir du mysqldump d'origine.

Toutes les options sont expliquées sur la page github, mais plus ou moins sont auto-explicatives:

$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
);
Diego
la source
2
Même sur les serveurs qui ont execet / ou sont shell_execdésactivés par la sécurité, mysqldump-php fonctionne très bien! Je viens de l'essayer maintenant sur les serveurs d' Umbler et j'ai réussi le vidage. Merci beaucoup pour le tuyau!
giovannipds
c'est parfait pour les serveurs qui n'ont pas de commandes shell mysql disponibles également!
Andrej
9

Veuillez vous référer au lien suivant qui contient un scriptlet qui vous aidera: http://davidwalsh.name/backup-mysql-database-php

Remarque: ce script peut contenir des bogues avec des types de données NULL

André Puel
la source
Merci, ceci est un plan B pratique si "shell_exec () a été désactivé pour des raisons de sécurité" (
voilà
1
Notez que cela utilise des commandes mysql obsolètes au lieu de mysqli.
Pascal Raszyk
"Bogues avec des types de données NULL" semble être un problème pour une solution de sauvegarde.
alexis le
7

Pour des raisons de sécurité, il est recommandé de spécifier le mot de passe dans un fichier de configuration et non dans la commande (un utilisateur peut exécuter un ps aux | grep mysqldumpet voir le mot de passe).

//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);
Constantin Galbenu
la source
5

Ici vous pouvez trouver une solution complète pour vider la structure et les données mysql comme dans PMA (et sans utiliser exec, passthru, etc.):

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

C'est une fourchette du projet dszymczuk avec mes améliorations.

L'utilisation est simple

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

?>

fonctionne comme un charme :-)

ANTARA
la source
Cela fonctionne - mais il produit une sortie différente de celle du mysqldump PHPMYADMIN. Pourquoi ? Il manque des données pendant que ma sauvegarde PHPMYADMIN est terminée.
ledawg
@ Ledew-de: Les données ne doivent pas être incluses dans le vidage uniquement si l'option skip_data => true est passée en paramètre
ANTARA
3

Tant que vous êtes autorisé à utiliser exec () , vous pouvez exécuter des commandes shell via votre code PHP.

Donc, en supposant que vous sachiez comment écrire le mysqldump dans la ligne de commande, ie

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

alors vous pouvez l'utiliser comme paramètre de la fonction exec ().

exec("mysqldump -u mysqluser -p my_database > my_database_dump.sql");
Charliefortune
la source
3

La réponse de MajorLeo m'a orienté dans la bonne direction, mais cela n'a pas fonctionné pour moi. J'ai trouvé ce site qui suit la même approche et qui a fonctionné.

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

J'espère que cela aide quelqu'un d'autre!

Matías Cánepa
la source
Le vôtre renvoie ici la sortie à l'utilisateur final, n'est-ce pas? IE lors de l'exécution, il le produit d'une manière que vous pouvez copier / coller? Si tel est le cas, cela n'atteindra pas ce que la réponse acceptée a fait - crée simplement le fichier sur le serveur pour que je puisse le récupérer par scp.
Thomas Ward du
@ThomasW. Ce code fait deux choses: il génère un fichier enregistré sur le serveur et affiche la boîte de dialogue de téléchargement. Si vous souhaitez simplement stocker le fichier, ne faites pas les parties header () et passthru (). Et si vous n'avez besoin que de l'emplacement du fichier, vous pouvez toujours faire écho aux variables $ dir & $ filename .... Peu importe ce que vous choisissez, vous pouvez toujours accéder au fichier via SCP
Matías Cánepa
0

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

Vous pouvez étendre la commande avec toutes les options que mysqldump prend bien sûr. Utilisez man mysqldumppour plus d'options (mais je suppose que vous le saviez;))

Rem.co
la source
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;

Fuad Hasan
la source
0

Aucun des codes ci-dessus n'a fonctionné pour moi. J'utilise Windows. Le code ci-dessous a fonctionné pour moi ...

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

Cela enregistrera le fichier dans votre dossier de projet en fonction de votre requête, quelles que soient les données souhaitées.

Swarnim dixit
la source
Cette solution est essentiellement imparfaite, car elle crée des chaînes SQL incorrectes
Votre bon sens
-1

Pour vider la base de données en utilisant shell_exec (), voici la méthode:

shell_exec('mysqldump -h localhost -u username -ppassword databasename  | gzip > dbname.sql.gz');
Digisha
la source
-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");


?>
PradeepJangid
la source