Frage

Ich erstelle ein Installationsskript für eine Anwendung, die ich entwickle und benötigen Datenbanken aus PHP dynamisch zu erstellen. Ich habe es die Datenbank zu erstellen, aber jetzt muss ich in mehreren SQL-Dateien laden. Ich hatte geplant, um die Datei zu öffnen und eine Zeile zu einem Zeitpunkt mysql_query -., Bis ich auf den Schema-Dateien gesucht und erkennen, dass sie nicht nur eine Abfrage pro Zeile

So, wie lade ich eine SQL-Datei in PHP (wie phpMyAdmin tut mit seinem Importbefehl)?

War es hilfreich?

Lösung

Ich bekomme das Gefühl, dass jeder hier, die diese Frage beantwortet ist nicht weiß, was es ist wie ein Web-Anwendungsentwickler zu sein, die Menschen, die Anwendung auf ihren eigenen Servern zu installieren. Shared Hosting, vor allem, nicht zulässt, dass Sie SQL wie die „LOAD DATA“ Abfrage zuvor erwähnt verwenden. Die meisten gemeinsamen Rechnern auch nicht zulassen, dass Sie shell_exec verwenden.

Nun, das OP zu beantworten, Ihre beste Wette ist, um nur eine PHP-Datei zu erstellen, die Ihre Anfragen in einer Variablen enthält und sie gerade laufen kann. Wenn Sie bestimmt sind SQL-Dateien zu analysieren, sollten Sie in phpMyAdmin aussehen und einige Ideen bekommen für Daten immer aus .SQL auf diese Weise Dateien. Schauen Sie sich um auf anderen Web-Anwendungen, die Installateure haben, und Sie werden sehen, dass, anstatt verwenden SQL-Dateien für ihre Fragen, sie sie nur in PHP-Dateien verpacken und nur jede Saite durch mysql_query laufen oder was auch immer es ist, dass sie tun müssen, .

Andere Tipps

$db = new PDO($dsn, $user, $password);

$sql = file_get_contents('file.sql');

$qr = $db->exec($sql);

phpBB verwendet einige Funktionen, ihre Dateien zu analysieren. Sie sind ziemlich gut kommentiert (was für eine Ausnahme!), So können Sie einfach wissen, was sie tun (ich habe diese Lösung von http://www.frihost.com/forums/vt-8194.html ). hier die Lösung eines Ich habe es viel verwendet:

<php
ini_set('memory_limit', '5120M');
set_time_limit ( 0 );
/***************************************************************************
*                             sql_parse.php
*                              -------------------
*     begin                : Thu May 31, 2001
*     copyright            : (C) 2001 The phpBB Group
*     email                : support@phpbb.com
*
*     $Id: sql_parse.php,v 1.8 2002/03/18 23:53:12 psotfx Exp $
*
****************************************************************************/

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

/***************************************************************************
*
*   These functions are mainly for use in the db_utilities under the admin
*   however in order to make these functions available elsewhere, specifically
*   in the installation phase of phpBB I have seperated out a couple of
*   functions into this file.  JLH
*
\***************************************************************************/

//
// remove_comments will strip the sql comment lines out of an uploaded sql file
// specifically for mssql and postgres type files in the install....
//
function remove_comments(&$output)
{
   $lines = explode("\n", $output);
   $output = "";

   // try to keep mem. use down
   $linecount = count($lines);

   $in_comment = false;
   for($i = 0; $i &lt; $linecount; $i++)
   {
      if( preg_match("/^\/\*/", preg_quote($lines[$i])) )
      {
         $in_comment = true;
      }

      if( !$in_comment )
      {
         $output .= $lines[$i] . "\n";
      }

      if( preg_match("/\*\/$/", preg_quote($lines[$i])) )
      {
         $in_comment = false;
      }
   }

   unset($lines);
   return $output;
}

//
// remove_remarks will strip the sql comment lines out of an uploaded sql file
//
function remove_remarks($sql)
{
   $lines = explode("\n", $sql);

   // try to keep mem. use down
   $sql = "";

   $linecount = count($lines);
   $output = "";

   for ($i = 0; $i &lt; $linecount; $i++)
   {
      if (($i != ($linecount - 1)) || (strlen($lines[$i]) > 0))
      {
         if (isset($lines[$i][0]) && $lines[$i][0] != "#")
         {
            $output .= $lines[$i] . "\n";
         }
         else
         {
            $output .= "\n";
         }
         // Trading a bit of speed for lower mem. use here.
         $lines[$i] = "";
      }
   }

   return $output;

}

//
// split_sql_file will split an uploaded sql file into single sql statements.
// Note: expects trim() to have already been run on $sql.
//
function split_sql_file($sql, $delimiter)
{
   // Split up our string into "possible" SQL statements.
   $tokens = explode($delimiter, $sql);

   // try to save mem.
   $sql = "";
   $output = array();

   // we don't actually care about the matches preg gives us.
   $matches = array();

   // this is faster than calling count($oktens) every time thru the loop.
   $token_count = count($tokens);
   for ($i = 0; $i &lt; $token_count; $i++)
   {
      // Don't wanna add an empty string as the last thing in the array.
      if (($i != ($token_count - 1)) || (strlen($tokens[$i] > 0)))
      {
         // This is the total number of single quotes in the token.
         $total_quotes = preg_match_all("/'/", $tokens[$i], $matches);
         // Counts single quotes that are preceded by an odd number of backslashes,
         // which means they're escaped quotes.
         $escaped_quotes = preg_match_all("/(?&lt;!\\\\)(\\\\\\\\)*\\\\'/", $tokens[$i], $matches);

         $unescaped_quotes = $total_quotes - $escaped_quotes;

         // If the number of unescaped quotes is even, then the delimiter did NOT occur inside a string literal.
         if (($unescaped_quotes % 2) == 0)
         {
            // It's a complete sql statement.
            $output[] = $tokens[$i];
            // save memory.
            $tokens[$i] = "";
         }
         else
         {
            // incomplete sql statement. keep adding tokens until we have a complete one.
            // $temp will hold what we have so far.
            $temp = $tokens[$i] . $delimiter;
            // save memory..
            $tokens[$i] = "";

            // Do we have a complete statement yet?
            $complete_stmt = false;

            for ($j = $i + 1; (!$complete_stmt && ($j &lt; $token_count)); $j++)
            {
               // This is the total number of single quotes in the token.
               $total_quotes = preg_match_all("/'/", $tokens[$j], $matches);
               // Counts single quotes that are preceded by an odd number of backslashes,
               // which means they're escaped quotes.
               $escaped_quotes = preg_match_all("/(?&lt;!\\\\)(\\\\\\\\)*\\\\'/", $tokens[$j], $matches);

               $unescaped_quotes = $total_quotes - $escaped_quotes;

               if (($unescaped_quotes % 2) == 1)
               {
                  // odd number of unescaped quotes. In combination with the previous incomplete
                  // statement(s), we now have a complete statement. (2 odds always make an even)
                  $output[] = $temp . $tokens[$j];

                  // save memory.
                  $tokens[$j] = "";
                  $temp = "";

                  // exit the loop.
                  $complete_stmt = true;
                  // make sure the outer loop continues at the right point.
                  $i = $j;
               }
               else
               {
                  // even number of unescaped quotes. We still don't have a complete statement.
                  // (1 odd and 1 even always make an odd)
                  $temp .= $tokens[$j] . $delimiter;
                  // save memory.
                  $tokens[$j] = "";
               }

            } // for..
         } // else
      }
   }

   return $output;
}

$dbms_schema = 'yourfile.sql';

$sql_query = @fread(@fopen($dbms_schema, 'r'), @filesize($dbms_schema)) or die('problem ');
$sql_query = remove_remarks($sql_query);
$sql_query = split_sql_file($sql_query, ';');

$host = 'localhost';
$user = 'user';
$pass = 'pass';
$db = 'database_name';

//In case mysql is deprecated use mysqli functions. 
mysqli_connect($host,$user,$pass) or die('error connection');
mysqli_select_db($db) or die('error database selection');

$i=1;
foreach($sql_query as $sql){
echo $i++;
echo "<br />";
mysql_query($sql) or die('error in query');
}

?>

Die einfachste Lösung ist shell_exec () zu verwenden, den MySQL-Client mit dem SQL-Skript als Eingabe auszuführen. Dies könnte ein wenig langsamer laufen, weil sie gabeln, aber Sie können den Code in ein paar Minuten schreiben und dann nützlich, um an etwas arbeiten wieder. Schreiben eines PHP-Skript auszuführen jede SQL-Skript Sie Wochen in Anspruch nehmen könnte.

Unterstützung von SQL-Skripten ist komplexer als das, was die Menschen hier beschreiben, wenn Sie sicher sind, dass Ihr Skript enthält nur eine Teilmenge der Funktionalität von Skripten. Im Folgenden sind einige Beispiele für Dinge, die in einem gewöhnlichen SQL-Skript erscheinen mag, dass es komplex machen ein Skript zu codieren, es Zeile für Zeile zu interpretieren.

-- Comment lines cannot be prepared as statements
-- This is a MySQL client tool builtin command.  
-- It cannot be prepared or executed by server.
USE testdb;

-- This is a multi-line statement.
CREATE TABLE foo (
  string VARCHAR(100)
);

-- This statement is not supported as a prepared statement.
LOAD DATA INFILE 'datafile.txt' INTO TABLE foo;

-- This statement is not terminated with a semicolon.
DELIMITER //

-- This multi-line statement contains a semicolon 
-- but not as the statement terminator.
CREATE PROCEDURE simpleproc (OUT param1 INT)
BEGIN
  SELECT COUNT(*) INTO param1 FROM foo;
END
// 

Wenn Sie nur eine Teilmenge von SQL-Skripts unterstützen, mit Ausnahme einiger Sonderfälle wie die oben, dann ist es relativ einfach, einen PHP-Skript zu schreiben, die eine Datei liest und ausführen, die SQL-Anweisungen in der Datei. Aber wenn Sie einen gültigen SQL-Skript unterstützen wollen, das ist viel komplexer.


Siehe auch meine Antworten auf diese Fragen:

mysqli können mehrere Abfragen von einem ; getrennt laufen

Sie in der gesamten Datei lesen können und es auf einmal mit laufen mysqli_multi_query()

Aber, werde ich die erste sein, zu sagen, dass dies nicht die eleganteste Lösung.

In meinen Projekten habe ich nächste Lösung verwendet:

<?php

/**
 * Import SQL from file
 *
 * @param string path to sql file
 */
function sqlImport($file)
{

    $delimiter = ';';
    $file = fopen($file, 'r');
    $isFirstRow = true;
    $isMultiLineComment = false;
    $sql = '';

    while (!feof($file)) {

        $row = fgets($file);

        // remove BOM for utf-8 encoded file
        if ($isFirstRow) {
            $row = preg_replace('/^\x{EF}\x{BB}\x{BF}/', '', $row);
            $isFirstRow = false;
        }

        // 1. ignore empty string and comment row
        if (trim($row) == '' || preg_match('/^\s*(#|--\s)/sUi', $row)) {
            continue;
        }

        // 2. clear comments
        $row = trim(clearSQL($row, $isMultiLineComment));

        // 3. parse delimiter row
        if (preg_match('/^DELIMITER\s+[^ ]+/sUi', $row)) {
            $delimiter = preg_replace('/^DELIMITER\s+([^ ]+)$/sUi', '$1', $row);
            continue;
        }

        // 4. separate sql queries by delimiter
        $offset = 0;
        while (strpos($row, $delimiter, $offset) !== false) {
            $delimiterOffset = strpos($row, $delimiter, $offset);
            if (isQuoted($delimiterOffset, $row)) {
                $offset = $delimiterOffset + strlen($delimiter);
            } else {
                $sql = trim($sql . ' ' . trim(substr($row, 0, $delimiterOffset)));
                query($sql);

                $row = substr($row, $delimiterOffset + strlen($delimiter));
                $offset = 0;
                $sql = '';
            }
        }
        $sql = trim($sql . ' ' . $row);
    }
    if (strlen($sql) > 0) {
        query($row);
    }

    fclose($file);
}

/**
 * Remove comments from sql
 *
 * @param string sql
 * @param boolean is multicomment line
 * @return string
 */
function clearSQL($sql, &$isMultiComment)
{
    if ($isMultiComment) {
        if (preg_match('#\*/#sUi', $sql)) {
            $sql = preg_replace('#^.*\*/\s*#sUi', '', $sql);
            $isMultiComment = false;
        } else {
            $sql = '';
        }
        if(trim($sql) == ''){
            return $sql;
        }
    }

    $offset = 0;
    while (preg_match('{--\s|#|/\*[^!]}sUi', $sql, $matched, PREG_OFFSET_CAPTURE, $offset)) {
        list($comment, $foundOn) = $matched[0];
        if (isQuoted($foundOn, $sql)) {
            $offset = $foundOn + strlen($comment);
        } else {
            if (substr($comment, 0, 2) == '/*') {
                $closedOn = strpos($sql, '*/', $foundOn);
                if ($closedOn !== false) {
                    $sql = substr($sql, 0, $foundOn) . substr($sql, $closedOn + 2);
                } else {
                    $sql = substr($sql, 0, $foundOn);
                    $isMultiComment = true;
                }
            } else {
                $sql = substr($sql, 0, $foundOn);
                break;
            }
        }
    }
    return $sql;
}

/**
 * Check if "offset" position is quoted
 *
 * @param int $offset
 * @param string $text
 * @return boolean
 */
function isQuoted($offset, $text)
{
    if ($offset > strlen($text))
        $offset = strlen($text);

    $isQuoted = false;
    for ($i = 0; $i < $offset; $i++) {
        if ($text[$i] == "'")
            $isQuoted = !$isQuoted;
        if ($text[$i] == "\\" && $isQuoted)
            $i++;
    }
    return $isQuoted;
}

function query($sql)
{
    global $mysqli;
    //echo '#<strong>SQL CODE TO RUN:</strong><br>' . htmlspecialchars($sql) . ';<br><br>';
    if (!$query = $mysqli->query($sql)) {
        throw new Exception("Cannot execute request to the database {$sql}: " . $mysqli->error);
    }
}

set_time_limit(0);

$mysqli = new mysqli('localhost', 'root', '', 'test');
$mysqli->set_charset("utf8");

header('Content-Type: text/html;charset=utf-8');
sqlImport('import.sql');

echo "Peak MB: ", memory_get_peak_usage(true)/1024/1024;

Im Test SQL-Datei (41MB) Spitzenhalte- Nutzung: 3.25MB

Da ich nicht auf Antwort kommentieren kann, passen sie folgende Lösung zu verwenden:

$db = new PDO($dsn, $user, $password);

$sql = file_get_contents('file.sql');

$qr = $db->exec($sql);

Es ist ein Fehler in PHP PDO https://bugs.php.net/bug .php? id = 61613

db->exec('SELECT 1; invalidstatement; SELECT 2');

wird nicht Fehler aus oder false zurück (getestet auf PHP 5.5.14).

würde Mein Vorschlag an den Sourcecode von PHPMyBackup zu sehen sein. Es ist ein automatisierter PHP SQL-Loader. Sie werden, dass mysql_query finden nur lädt eine Abfrage zu einem Zeitpunkt, und Projekte wie PHPMyAdmin und PHPMyBackup haben bereits die harte Arbeit für Sie von Parsen der SQL die richtige Art und Weise geschehen. Bitte nicht neu erfinden das Rad: P

Eine aktualisierte Lösung von Plahcinski Lösung. Alternativ können Sie fopen und fread für größere Dateien verwenden:

$fp = file('database.sql', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$query = '';
foreach ($fp as $line) {
    if ($line != '' && strpos($line, '--') === false) {
        $query .= $line;
        if (substr($query, -1) == ';') {
            mysql_query($query);
            $query = '';
        }
    }
}

Sind Sie sicher, dass es nicht eine Abfrage pro Zeile? Ihr Texteditor Linien werden Einwickeln, aber in Wirklichkeit jede Abfrage in einer einzelnen Zeile sein kann.

Auf jeden Fall olle Methode scheint am besten. Wenn Sie Gründe haben, Abfragen einer zum Zeitpunkt ausführen können, sollten Sie in der Lage sein, in Ihrer Datei Zeile für Zeile zu lesen, dann am Ende jeder Abfrage das Semikolon verwenden zu begrenzen. Sie sind viel besser für Zeile in einer Datei Zeile zu lesen als zu versuchen, einen enormen String aufgeteilt werden, da sie viel freundlicher in dem Speicher werden Ihren Servers. Beispiel:

$query  = '';
$handle = @fopen("/sqlfile.sql", "r");

if ($handle) {
    while (!feof($handle)) {
        $query.= fgets($handle, 4096);

        if (substr(rtrim($query), -1) === ';') {
            // ...run your query, then unset the string
            $query = '';
        }
    }

    fclose($handle);
}

Natürlich müssen Sie Transaktionen und den Rest prüfen, ob Sie eine ganze Menge von Anfragen in einem Batch laufen lassen, aber es ist wahrscheinlich keine große Sache für ein neues Skript installieren.

Arbeiten auf Navicat Dumps. Möglicherweise muß der erste / * * / Kommentar navicat setzt in dump.

$file_content = file('myfile.sql');
$query = "";
foreach($file_content as $sql_line){
  if(trim($sql_line) != "" && strpos($sql_line, "--") === false){
    $query .= $sql_line;
    if (substr(rtrim($query), -1) == ';'){
      echo $query;
      $result = mysql_query($query)or die(mysql_error());
      $query = "";
    }
  }
 }

Versuchen Sie folgendes:

// SQL File
$SQLFile = 'YourSQLFile.sql';

// Server Name
$hostname = 'localhost';

// User Name
$db_user = 'root';

// User Password
$db_password = '';

// DBName
$database_name = 'YourDBName';

// Connect MySQL
$link = mysql_connect($hostname, $db_user, $db_password);

if (!$link) {
die("MySQL Connection error");
}

// Select MySQL DB
mysql_select_db($database_name, $link) or die("Wrong MySQL Database");

// Function For Run Multiple Query From .SQL File
function MultiQuery($sqlfile, $sqldelimiter = ';') {
set_time_limit(0);

if (is_file($sqlfile) === true) {
$sqlfile = fopen($sqlfile, 'r');

if (is_resource($sqlfile) === true) {
$query = array();
echo "<table cellspacing='3' cellpadding='3' border='0'>";

while (feof($sqlfile) === false) {
$query[] = fgets($sqlfile);

if (preg_match('~' . preg_quote($sqldelimiter, '~') . '\s*$~iS', end($query)) === 1) {
$query = trim(implode('', $query));

if (mysql_query($query) === false) {
echo '<tr><td>ERROR:</td><td> ' . $query . '</td></tr>';
} else {
echo '<tr><td>SUCCESS:</td><td>' . $query . '</td></tr>';
}

while (ob_get_level() &gt; 0) {
ob_end_flush();
}

flush();
}

if (is_string($query) === true) {
$query = array();
}
}
echo "</table>";

return fclose($sqlfile);
}
}

return false;
}

/* * * Use Function Like This: ** */

MultiQuery($SQLFile);
mysql_query("LOAD DATA LOCAL INFILE '/path/to/file' INTO TABLE mytable");

Kurz gesagt, die Art, wie ich dies getan haben, ist:

  1. Lesen Sie die Datei (db Dump zB $ mysqldump db > db.sql)

    $sql = file_get_contents(db.sql);
    
  2. es Importieren mit mysqli :: multi_query

    if ($mysqli->multi_query($sql)) {
        $mysqli->close();
    } else {
        throw new Exception ($mysqli->error);
    }
    

Watch out mysqli_query Asynchron-Abfragen unterstützt. Mehr hier: http://php.net/manual/en/mysqli.multi -query.php und hier https://stackoverflow.com/a/6652908/2002493

Es sei denn, Sie planen, importieren großen SQL-Dateien, nur die gesamte Datei in den Speicher gelesen, und es als eine Abfrage ausführen.

Es ist schon eine Weile her, seit ich PHP verwendet habe, so, Pseudo-Code:

all_query = read_file("/my/file.sql")
con = mysql_connect("localhost")
con.mysql_select_db("mydb")
con.mysql_query(all_query)
con.close()

Es sei denn, die Dateien sehr groß sind (sagen wir, über mehrere Megabyte), gibt es keinen Grund, sie auszuführen Line-at-a-time, oder versuchen Sie und teilen Sie es in mehrere Abfragen (durch Spaltung ; verwenden, die wie ich auf cam8001 des kommentiert Antwort wird brechen, wenn die Abfrage Semikolons innerhalb von Strings hat) ..

Das The Best Code für Wiederherstellung von SQL von PHP 100% Goooood verwenden können!  Viele Viele

$file_content = file('myfile.sql');
$query = "";
foreach($file_content as $sql_line){
if(trim($sql_line) != "" && strpos($sql_line, "--") === false){
 $query .= $sql_line;
 if (substr(rtrim($query), -1) == ';'){
   echo $query;
   $result = mysql_query($query)or die(mysql_error());
   $query = "";
  }
 }
}

Der einfachste und schnellste Weg, phpMyAdmin Dump MySQL-Dump-Datei ..

zu laden und analysieren
$ mysql -u username -p -h localhost dbname < dumpfile.sql 

bemerkte ich, dass die PostgreSQL PDO-Treiber nicht zulässt Skripte durch ein Semikolon getrennt auszuführen. Um eine SQL-Datei auf einem beliebigen Datenbank mit PDO auszuführen ist es notwendig, die Anweisungen in PHP-Code selbst zu spalten. Hier ist eine Lösung, die ganz gut zu funktionieren scheint:

https://github.com/diontruter /migrate/blob/master/src/Diontruter/Migrate/SqlScriptParser.php

Die referenzierte Klasse den Trick für mich in einer Datenbank unabhängige Art und Weise getan hat, bitte ich um Nachricht, wenn es irgendwelche Probleme. Hier ist, wie Sie das Skript nach dem Hinzufügen es zu einem Projekt verwenden:

$pdo = new PDO($connectionString, $userName, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$parser = new SqlScriptParser();
$sqlStatements = $parser->parse($fileName);
foreach ($sqlStatements as $statement) {
    $distilled = $parser->removeComments($statement);
    if (!empty($distilled)) {
        $statement = $pdo->prepare($sql);
        $affectedRows = $statement->execute();
    }
}

Keine der Lösungen, die ich hier gesehen habe zu behandeln, um das Trennzeichen zu ändern, während eine gespeicherte Prozedur auf einem Server erstellen, wo ich nicht auf, den Zugang zu LOAD DATA INFILE zählen kann. Ich hatte gehofft, zu finden, dass jemand hatte bereits gelöst dies ohne den phpMyAdmin-Code scheuern, die es herauszufinden. Wie viele andere war auch ich in den Prozess der Suche nach einer anderen Person GPL'ed Art und Weise, es zu tun, da ich GPL-Code selbst schreibe.

Einige PHP-Bibliotheken können eine SQL-Datei aus mehreren SQL-Anweisungen analysieren, explodieren sie richtig (nicht mit einem einfachen „“ explodiert, natürlich), und die sie ausführen.

Zum Beispiel überprüfen Phing 's PDOSQLExecTask

Sie einfach das Problem für alle neu zu formulieren:

PHP mysql_query, automatisch End-abgrenzt jede SQL-Befehle, und zusätzlich ist sehr vage, so in seinem Handbuch zu tun. Alles über einen Befehl einen Fehler ergeben.

Auf der anderen mysql_query ist in Ordnung, mit einem String mit SQL-Stil Kommentaren, \ n, \ r ..

Die Begrenzung der mysql_query zeigt sich, dass der SQL-Parser, das Problem meldet beim nächsten Befehl zu sein, direkt z.

 You have an error in your SQL syntax; check the manual that corresponds to your
 MySQL server version for the right syntax to use near 'INSERT INTO `outputdb:`
 (`intid`, `entry_id`, `definition`) VALUES...

Hier ist eine schnelle Lösung: (Vorausgesetzt, gut formatiert SQL;

$sqlCmds = preg_split("/[\n|\t]*;[\n|\t]*[\n|\r]$/", $sqlDump);

Viele Gastgeber werden nicht zulassen, dass Sie Ihre eigene Datenbank durch PHP erstellen, aber Sie scheinen, dass gelöst zu haben.
Sobald die DB erstellt wurde, können Sie manipulieren und füllen Sie es einfach:

  

mysql_connect ( "localhost");
  mysql_query ( "SOURCE file.sql");

Einige Jungs (Plahcinski) vorgeschlagen, diesen Code:

$file_content = file('myfile.sql');
$query = "";
foreach($file_content as $sql_line){
  if(trim($sql_line) != "" && strpos($sql_line, "--") === false){
    $query .= $sql_line;
    if (substr(rtrim($query), -1) == ';'){
      echo $query;
      $result = mysql_query($query)or die(mysql_error());
      $query = "";
    }
  }
 }

, aber ich würde es mit dem einen aktualisieren, die für mich gearbeitet:

 //selecting my database
    $database = 'databaseTitleInFile';
    $selectDatabase = mysql_select_db($database, $con);
    if(! $selectDatabase )
    {
      die('Could not select the database: ' . mysql_error());
    }
    echo "The database " . $database . " selected successfully\n";
//reading the file
    $file_path='..\yourPath\to\File';
    if(!file_exists($file_path)){
        echo "File Not Exists";
    }
    $file_content = file_get_contents($file_path);
    $array = explode("\n", $file_content)
//making queries
    $query = "";
        foreach($array as $sql_line){
$sql_line=trim($sql_line);
          if($sql_line != "" && substr($sql_line, 0, 2) === "--" && strpos($sql_line, "/*") === false){
            $query .= $sql_line;
            if (substr(rtrim($query), -1) == ';'){
              $result = mysql_query($query)or die(mysql_error());
              $query = "";
            }
          }
         }

, weil es umfassender ist. ; -)

Dies kann hilfreich sein ->

Mehr oder weniger das, was sie tut, ist zuerst die Zeichenfolge in die Funktion (der file_get_contents () Wert Ihres file.sql) gegeben zu nehmen und entfernen Sie die alle Zeilenumbrüche. Dann teilt er die Daten durch das „;“ Charakter. Weiter geht es in eine while-Schleife, bei jeder Zeile des Arrays suchen, die erstellt wird. Wenn die Zeile „`“Zeichen enthält, wird es wissen, dass es eine Abfrage und execture die MyQuery () Funktion für die gegebenen Zeilendaten.

Code:

function myquery($query) {

mysql_connect(dbhost, dbuser, dbpass);

mysql_select_db(dbname);

$result = mysql_query($query);

if (!mysql_errno() && @mysql_num_rows($result) > 0) {
}

else {

$result="not";
}
mysql_close();

return $result;

}



function mybatchquery ($str) {

$sql = str_replace("\n","",$str)

$sql = explode(";",$str);

$x=0;

while (isset($str[$x])) {

if (preg_match("/(\w|\W)+`(\w|\W)+) {

myquery($str[$x]);

}

$x++

}

return TRUE;

}




function myrows($result) {

$rows = @mysql_num_rows($result);

return $rows;
}




function myarray($result) {

$array = mysql_fetch_array($result);

return $array;
}




function myescape($query) {

$escape = mysql_escape_string($query);

return $escape;
}



$str = file_get_contents("foo.sql");
mybatchquery($str);

Warum nicht den Code aus phpMyAdmin und verwenden Sie diese? Es ist Open Source, nachdem alle ...

Ich benutze das die ganze Zeit:

$sql = explode(";",file_get_contents('[your dump file].sql'));// 

foreach($sql as $query)
 mysql_query($query);

Ich hoffe, dass der folgende Code das Problem ziemlich gut lösen.
    

//Empty all tables' contents

$result_t = mysql_query("SHOW TABLES");
while($row = mysql_fetch_assoc($result_t))
{
mysql_query("TRUNCATE " . $row['Tables_in_' . $mysql_database]);
}
// Temporary variable, used to store current query
$templine = '';
// Read in entire file
$lines = file($filename);
// Loop through each line
foreach ($lines as $line)
{
// Skip it if it's a comment
if (substr($line, 0, 2) == '--' || $line == '')
    continue;

// Add this line to the current segment
$templine .= $line;
// If it has a semicolon at the end, it's the end of the query
if (substr(trim($line), -1, 1) == ';')
{
    // Perform the query
    mysql_query($templine) or print('Error performing query \'<strong>' . $templine . '\': ' . mysql_error() . '<br /><br />');
    // Reset temp variable to empty
    $templine = '';
}
}

?>

für mich tatsächlich funktioniert:

/* load sql-commands from a sql file */
function loadSQLFromFile($url)
{
    // ini_set ( 'memory_limit', '512M' );
    // set_time_limit ( 0 );

    global $settings_database_name;
    global $mysqli_object; global $worked; $worked = false;

    $sql_query = "";

    // read line by line
    $lines = file($url);
    $count = count($lines);

    for($i = 0;$i<$count;$i++)
    {
        $line = $lines[$i];
        $cmd3 = substr($line, 0, 3);
        $cmd4 = substr($line, 0, 4);
        $cmd6 = substr($line, 0, 6);
        if($cmd3 == "USE")
        {
            // cut away USE ``;
            $settings_database_name = substr($line, 5, -3);
        }
        else if($cmd4 == "DROP")
        {
            $mysqli_object->query($line); // execute this line
        }
        else if(($cmd6 == "INSERT") || ($cmd6 == "CREATE"))
        {
            // sum all lines up until ; is detected
            $multiline = $line;
            while(!strstr($line, ';'))
            {
                $i++;
                $line = $lines[$i];
                $multiline .= $line;
            }
            $multiline = str_replace("\n", "", $multiline); // remove newlines/linebreaks
            $mysqli_object->query($multiline); // execute this line
        }       
    }

    return $worked;
}
?>

Ich habe ein Umfeld, in dem kein mysql-Tool oder phpMyAdmin nur meine PHP-Anwendung auf einem anderen Host zu einem MySQL-Server zu verbinden, aber ich brauche Skripte von mysqldump oder myadmin exportierte auszuführen. Zur Lösung des Problems ich ein Skript multi_query erstellt wie ich bereits erwähnt hier

Es kann mysqldump Ausgang und phpMyAdmin Exporte ohne mysql Kommandozeilen-Tool bearbeiten. Ich habe auch eine gewisse Logik mehr Migrationsdateien basierend auf Zeitstempel in DB wie Rails gespeichert zu verarbeiten. Ich weiß, dass es mehr Fehlerbehandlung muss aber zur Zeit macht die Arbeit für mich.

Check it out: https://github.com/kepes/php-migration

Es ist reine PHP und keine anderen Werkzeuge benötigt. Wenn Sie nicht über eine Benutzereingabe mit nur Skripte gemacht von den Entwicklern oder Export-Tool verarbeiten können Sie es sicher verwenden.

Dies ist aus einem Projekt arbeite ich an. Grundsätzlich nimmt eine beliebige Textdatei und extrahiert die SQL-Anweisungen, während Kommentare und unentgeltliche Zeilenumbrüche ignoriert.

<?php

  /*
     ingestSql(string) : string

     Read the contents of a SQL batch file, stripping away comments and
     joining statements that are broken over multiple lines with the goal
     of producing lines of sql statements that can be successfully executed
     by PDO exec() or execute() functions.

     For example:
       -- My SQL Batch
       CREATE TABLE foo(
         bar VARCHAR(80),
         baz INT NOT NULL);

     Becomes:
       CREATE TABLE foo(bar VARCHAR(80), baz INT NOT NULL);
  */

  function ingestSql($sqlFilePath=__DIR__ . "/create-db.sql") {
    $sqlFile = file($sqlFilePath);
    $ingestedSql = "";
     $statement = "";
    foreach($sqlFile as $line) {

      // Ignore anything between a double-dash and the end of the line.
      $commentStart = strpos($line, "--");
      if ($commentStart !== false) {
        $line = substr($line, 0, $commentStart);
      }

      // Only process non-blank lines.
      if (strlen($line)) {

        // Remove any leading and trailing whitespace and append what's
        // left of the line to the current statement.
        $line = trim($line);
        $statement .= $line;

        // A semi-colon ends the current statement.  Otherwise what was a
        // newline becomes a single space;
        if (substr($statement, -1) == ";") {
          $ingestedSql .= $statement;
          $statement = "\n";
        }
        else {
          $statement .= " ";
        }
      }
    }

    return $ingestedSql;
  }

?>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top