2 Stimmen

PHP Database Dump Script - gibt es irgendwelche Probleme?

Ich habe eine PHP-Funktion gefunden, um eine mySQL-Datenbank zu dumpen, die jemand anderes geschrieben hatte, und habe sie dann bereinigt und ein wenig formatiert. Ich wollte wissen, ob ich eine Kritik dazu bekommen kann. Ich habe es ausgeführt, getestet es auf einem Wordpress-Blog und die DB vollständig wiederhergestellt, aber wollte einige andere Augen auf den Code zu bekommen.

Insbesondere suche ich nach Feedback zu:

  • Alles, was die Daten beschädigen könnte - nicht korrektes Escaping usw.
  • Verstoß gegen bewährte Praktiken/Grundsätze
  • Sicherheitsfragen
  • Alles, was Sie sonst noch für problematisch halten

ANMERKUNG: Ich bin NICHT auf der Suche nach mysqldump, möchte ich dieses Sql-Backup vollständig aus dem Code generieren. Ich erkenne auch, dass der Dateiname zufällig generiert werden könnte, aber die SQL-Datei wird auch auf Dropbox hochgeladen werden, und ich möchte es unter dem gleichen Namen zu versionieren.

Gracias.

Code:

  // Variables
  $dbHost = 'DBHOST';
  $dbUser = 'DBUSER';
  $dbPassword = 'DBPASSWORD';
  $dbName = 'DBNAME';
  $tables = '*';
  $fileName = 'mydatabase.sql';

  // Logic
    $link = @mysql_connect($dbHost, $dbUser, $dbPassword);
    $db = @mysql_select_db($dbName, $link);

if(!$link || !$db)
 die("Database Error");

//get all of the tables
if($tables == '*') {

$tables = array();
$result = mysql_query('SHOW TABLES');

while($row = mysql_fetch_row($result)) {
  $tables[] = $row[0];
    }
}

else $tables = is_array($tables) ? $tables : explode(',',$tables);

// Loop through tables    
foreach($tables as $table) {

    $result = mysql_query('SELECT * FROM '. $table);
    $num_fields = mysql_num_fields($result);
    $return.= 'DROP TABLE IF EXISTS ' . $table . ';';
  $createTable = mysql_fetch_row(mysql_query('SHOW CREATE TABLE ' . $table));
    $return .= "\n\n" . $createTable[1] . ";\n\n";

    for ($i = 0; $i < $num_fields; $i++) 
    {
        while($row = mysql_fetch_row($result))
        {

            $return.= 'INSERT INTO ' . $table . ' VALUES(';

            for($j = 0; $j < $num_fields; $j++) {

        $row[$j] = addslashes($row[$j]);
        $row[$j] = ereg_replace("\n","\\n", $row[$j]);

        if (isset($row[$j])) { 
          $return .= '"' . $row[$j] . '"' ; 
        } 

        else { 
          $return .= '""'; 
        }

        if ($j < ($num_fields-1)) { 
          $return .= ','; 
        }
            }
            $return .= ");\n";
        }
    }

    $return .="\n\n\n";

}

// Save the file
$handle = fopen($fileName, 'w+');
fwrite($handle, $return);
fclose($handle);

4voto

Bill Karwin Punkte 493880

Dieses Skript hat ernsthafte, verhandlungsbedrohende Probleme. Es funktioniert nur für die trivialste Datenbank.

  • NULLs werden nicht unterstützt.
  • Zeichensätze werden nicht berücksichtigt.
  • Tabellennamen werden nicht abgegrenzt.
  • Es werden nur Tabellen unterstützt, nicht jedoch Ansichten, gespeicherte Verfahren, Trigger, Funktionen usw.
  • addslashes() ist nicht zeichensatzsicher .
  • mysql_query() holt vor. tous Wenn Sie also eine Tabelle mit Millionen von Zeilen abfragen, überschreiten Sie Ihr PHP-Speicherlimit. Verwenden Sie mysql_unbuffered_query() stattdessen. Bei näherem Nachdenken sehe ich, dass Sie die gesamte Ausgabe in $return sammeln, so dass dies strittig ist.
  • Ihre Unterdrückung von Fehlern mit dem @ Betreiber ist eine schlechte Praxis. Prüfen Sie auf Fehler und geben Sie eine informative Meldung aus.

Ihre Forderung, mysqldump nicht zu verwenden, ist absurd.

Warum sollten Sie sich so viel Arbeit machen und das Rad neu erfinden, wenn es doch so falsch ist? Führen Sie einfach mysqldump über shellexec() .


Siehe auch:

2voto

Mithun Sreedharan Punkte 47729

Versuchen Sie mysql Befehl oder mysqldump Befehl

0 Stimmen

Der Autor möchte mysqldump nicht verwenden, sagt in der Frage

1voto

Hammerite Punkte 20657

Zeichensätze? Vielleicht SET NAMES utf8 wäre eine gute Ergänzung.

Was geschieht außerdem, wenn die Datenbank Ansichten enthält?

1voto

Redlab Punkte 2952

Falls es sich um eine sehr große Datenbank handelt, die gedumpt werden muss, stellen Sie sicher, dass Ihr Server (und der maximale Ausführungsspeicher von php pro Skript) genug Speicher hat, um den gesamten $return im Speicher zu halten, andernfalls sollten Sie besser einmal in eine Datei flushen, oder jede Zeile.

0voto

Mahdi Bagheri Punkte 1

Backup DB erstellen :

<?php

$dbHost = 'DBHOST';
$dbUser = 'DBUSER';
$dbPassword = 'DBPASSWORD';
$dbName = 'DBNAME';
$tables = '*';

backup_tables($dbHost,$dbUser,$dbPassword,$tables);

/* backup the db OR just a table */
function backup_tables($host,$user,$pass,$name,$tables = '*')
{

    $db = new PDO("mysql:host=$host;dbname=$name;", $user, $pass);

    //get all of the tables
    if($tables == '*')
    {
        $tables = array();

        $result = $db->query('SHOW TABLES');

        $tables= $result->fetchAll(PDO::FETCH_COLUMN, 0);

    }
    else
    {
        $tables = is_array($tables) ? $tables : explode(',',$tables);
    }

    $return="";

    //cycle through
    foreach($tables as $table)
    {

        $return.= 'DROP TABLE  IF EXISTS '.$table.';';
        $result=$db->query('SHOW CREATE TABLE '.$table);
        $row2 = $result->fetch(PDO::FETCH_NUM);
        $return.= "\n\n".$row2[1].";\n\n";

        $result = $db->query('SELECT * FROM '.$table);

        foreach ($result->fetchAll(PDO::FETCH_ASSOC) as  $key=>$value) {

            // build query...
           $return .= "INSERT INTO $table (`".implode("`, `", array_keys($value))."`)
            VALUES ('".implode("', '", $value)."');\n\n";

        }

        $return.="\n\n\n";
    }

    //save file
    $handle = fopen('db-backup-'.date('Y-m-d--H-i-s').'-'.(md5(implode(',',$tables))).'.sql','w+');
    fwrite($handle,$return);
    fclose($handle);
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X