it-swarm.com.de

Laden von .sql-Dateien von innen PHP

Ich erstelle ein Installationsskript für eine Anwendung, die ich entwickle, und muss Datenbanken dynamisch aus PHP heraus erstellen. Ich habe es, um die Datenbank zu erstellen, aber jetzt muss ich mehrere .sql-Dateien laden. Ich hatte geplant, die Datei und mysql_query Zeile für Zeile zu öffnen - bis ich mir die Schemadateien ansah und erkannte, dass sie nicht nur eine Abfrage pro Zeile sind.

Wie lade ich also eine SQL-Datei aus PHP (wie PhpMyAdmin mit seinem Importbefehl)?

59
Josh Smeaton

Ich habe das Gefühl, dass jeder, der diese Frage beantwortet hat, nicht weiß, wie es ist, ein Webanwendungsentwickler zu sein, der es den Leuten erlaubt, die Anwendung auf ihren eigenen Servern zu installieren. Shared Hosting erlaubt insbesondere nicht die Verwendung von SQL wie die zuvor erwähnte Abfrage "LOAD DATA". Die meisten gemeinsam genutzten Hosts erlauben auch nicht die Verwendung von Shell_exec.

Um das OP zu beantworten, ist es am besten, eine PHP -Datei aufzubauen, die Ihre Abfragen in einer Variablen enthält und diese einfach ausführen kann. Wenn Sie die .sql-Dateien analysieren möchten, sollten Sie sich phpMyAdmin ansehen und ein paar Ideen erhalten, wie Sie auf diese Weise Daten aus den .sql-Dateien holen können. Schauen Sie sich andere Webanwendungen an, die über Installationsprogramme verfügen, und Sie werden feststellen, dass sie die SQL-Dateien nicht für ihre Abfragen verwenden, sondern sie in PHP -Dateien packen und jeden String über mysql_query oder was auch immer ausführen Sie müssen es tun.

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

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

$qr = $db->exec($sql);
65
Luis Granja

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

<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                : [email protected]
*
*     $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');
}

?>
58
Yasin

Die einfachste Lösung ist, Shell_exec () zu verwenden, um den Mysql-Client mit dem SQL-Skript als Eingabe auszuführen. Dies kann etwas langsamer verlaufen, weil es sich verzahnen muss, aber Sie können den Code in ein paar Minuten schreiben und dann wieder an etwas Nützlichem arbeiten. Das Schreiben eines PHP -Skripts zum Ausführen von SQL-Skripts kann Wochen dauern. 

Die Unterstützung von SQL-Skripts ist komplexer als das, was die Leute hier beschreiben, es sei denn, Sie sind sicher, dass Ihr Skript nur einen Teil der Funktionalität von Skripts enthält. Im Folgenden finden Sie einige Beispiele für Dinge, die in einem gewöhnlichen SQL-Skript vorkommen können, was die Codierung eines Skripts zur zeilenweisen Interpretation eines Skripts erschwert.

-- 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, ausgenommen einige Eckpunkte wie die oben genannten, ist es relativ einfach, ein PHP -Skript zu schreiben, das eine Datei liest und die SQL-Anweisungen innerhalb der Datei ausführt. Wenn Sie jedoch ein gültiges SQL-Skript unterstützen möchten, ist dies viel komplexer.


Siehe auch meine Antworten auf diese verwandten Fragen:

27
Bill Karwin

In meinen Projekten habe ich die 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;

Bei Test-SQL-Datei (41 MB) Hauptspitzenauslastung: 3,25 MB

10
Gromo

mysqli kann mehrere Abfragen ausführen, die durch einen ; getrennt sind. 

sie können die gesamte Datei einlesen und mit mysqli_multi_query() auf einmal ausführen.

Aber ich werde als erster sagen, dass dies nicht die eleganteste Lösung ist.

10
phatduckk

Da ich die Antwort nicht kommentieren kann, sollten Sie folgende Lösung verwenden:

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

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

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

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

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

es wird kein Fehler ausgegeben oder false zurückgegeben (getestet unter PHP 5.5.14). 

5
zstate

Eine aktualisierte Lösung der 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 = '';
        }
    }
}
4
sanneo

Mein Vorschlag wäre, sich den Quellcode von PHPMyBackup anzusehen. Es ist ein automatisierter PHP SQL-Loader. Sie werden feststellen, dass mysql_query jeweils nur eine Abfrage lädt, und Projekte wie PHPMyAdmin und PHPMyBackup haben bereits die harte Arbeit geleistet, die SQL auf korrekte Weise zu analysieren. Bitte das Rad nicht neu erfinden: P

4
SchizoDuckie

Funktioniert auf Navicat-Dumps. Möglicherweise müssen Sie den ersten/* */- Kommentar von navicat ablegen.

$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 = "";
    }
  }
 }
3
Plahcinski
mysql_query("LOAD DATA LOCAL INFILE '/path/to/file' INTO TABLE mytable");
3
olle

Versuche dies:

// 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);
3
Neeraj Singh

Sind Sie sicher, dass es nicht eine Abfrage pro Zeile gibt? Ihr Texteditor kann Zeilen umbrechen, aber in Wirklichkeit kann jede Abfrage in einer einzelnen Zeile sein.

Jedenfalls scheint die Methode von olle am besten zu sein. Wenn Sie Gründe haben, eine Abfrage zu einem bestimmten Zeitpunkt auszuführen, sollten Sie Ihre Datei Zeile für Zeile einlesen können und dann das Semikolon am Ende jeder Abfrage zur Begrenzung verwenden. Sie können Zeile für Zeile besser in einer Datei lesen, als eine riesige Zeichenfolge aufzuteilen, da dies für Ihren Server viel günstiger ist. 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 in Betracht ziehen, wenn Sie viele Abfragen in einem Batch ausführen, aber für ein Skript zur Neuinstallation ist das wahrscheinlich keine große Sache.

3
cam8001

In Kürze habe ich dies getan:

  1. Lese die Datei (ein Db-Dump, zB $ mysqldump db > db.sql)

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

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

Beachten Sie, dass mysqli_query asynchrone Abfragen unterstützt. Mehr hier: http://php.net/manual/de/mysqli.multi-query.php und hier https://stackoverflow.com/a/6652908/2002493

3
Portmanteau

Wenn Sie nicht vorhaben, huge .sql-Dateien zu importieren, lesen Sie einfach die gesamte Datei in den Speicher und führen Sie sie als Abfrage aus.

Es ist schon eine Weile her, seit ich PHP benutzt habe, also 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()

Wenn die Dateien nicht riesig sind (z. B. über mehrere Megabyte), gibt es keinen Grund, sie Zeile für Zeile auszuführen oder sie in mehrere Abfragen aufzuteilen (durch Aufteilen von ;, was, wie ich in der Antwort von cam8001 kommentierte, dies tun wird break, wenn die Abfrage Semikolons innerhalb von Zeichenfolgen enthält).

2
dbr

Dieser The Best Code Für die Wiederherstellung von SQL durch PHP kann 100% Goooood! .__ verwendet werden. Vielen Dank 

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

Der einfachste und schnellste Weg, den phpmyadmin-Dump der mysql-Dump-Datei zu laden und zu analysieren.

$ mysql -u username -p -h localhost dbname < dumpfile.sql 
2
Nemanja

Nur um das Problem für alle zu wiederholen:

Mysql_query von PHP beendet jedes SQL-Kommando automatisch und begrenzt es im Handbuch auch sehr vage. Alles, was über einen Befehl hinausgeht, führt zu einem Fehler.

Auf der anderen Seite ist mysql_query in Ordnung mit einer Zeichenfolge, die Kommentare im SQL-Stil enthält,\n,\r ..

Die Einschränkung von mysql_query offenbart sich darin, dass der SQL-Parser das Problem als direkt beim nächsten Befehl meldet, 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 formatiertes SQL;

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

Bei keiner der Lösungen, die ich hier gesehen habe, geht es darum, das Trennzeichen zu ändern, während eine gespeicherte Prozedur auf einem Server erstellt wird, auf die ich keinen Zugriff auf LOAD DATA INFILE haben kann. Ich hatte gehofft, dass jemand dieses Problem bereits gelöst hatte, ohne den Code von phpMyAdmin durchsuchen zu müssen, um es herauszufinden. Wie andere war auch ich dabei, nach einer GPL-Methode eines anderen zu suchen, da ich selbst GPL-Code schreibe.

1
K B

Einige PHP -Bibliotheken können eine SQL-Datei analysieren, die aus mehreren SQL-Anweisungen besteht, diese richtig auflösen (und dabei kein einfaches ";" - "explodieren"). 

Überprüfen Sie beispielsweise Phing 's PDOSQLExecTask

1

Bei vielen Hosts können Sie keine eigene Datenbank über PHP erstellen. Dies scheint jedoch gelöst zu sein.
Nachdem die Datenbank erstellt wurde, können Sie sie einfach bearbeiten und füllen:

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

1
SamGoody

Das kann hilfreich sein ->

Es ist mehr oder weniger, wenn Sie zuerst die Zeichenfolge der Funktion (den Wert file_get_contents () Ihrer file.sql) verwenden und alle Zeilenumbrüche entfernen. Dann teilt es die Daten durch das ";" Charakter. Als nächstes geht es in eine while-Schleife und betrachtet jede Zeile des erstellten Arrays. Wenn die Zeile das Zeichen "` "enthält, wird sie wissen, dass es sich um eine Abfrage handelt und die myquery () - Funktion für die angegebenen Zeilendaten abhört.

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);
1
White Rabbit

Einige Leute (Plahcinski) haben diesen Code vorgeschlagen:

$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 aktualisieren, der für mich funktionierte:

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

1

Dies ist aus einem Projekt, an dem ich arbeite. Nimmt im Allgemeinen jede Textdatei und extrahiert die SQL-Anweisungen, während Kommentare und unbegründete Zeilenumbrüche ignoriert werden.

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

?>
0
Dave H.

Ich habe eine Umgebung, in der kein MySQL-Tool oder phpmyadmin nur meine PHP-Anwendung mit einem MySQL-Server auf einem anderen Host verbindet, aber ich muss Skripts ausführen, die von MySQLDump oder Myadmin exportiert werden. Um das Problem zu lösen, habe ich ein Skript multi_query erstellt, wie ich hier erwähnte.

Es kann mysqldump-Ausgaben und phpmyadmin-Exporte ohne mysql-Befehlszeilentool verarbeiten. Ich habe auch eine Logik entwickelt, um mehrere Migrationsdateien basierend auf dem in DB gespeicherten Zeitstempel wie Rails zu verarbeiten. Ich weiß, dass es mehr Fehlerbehandlung erfordert, aber derzeit erledigt es die Arbeit für mich.

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

Es ist reines PHP und benötigt keine anderen Werkzeuge. Wenn Sie keine Benutzereingaben mit nur von Entwicklern erstellten Skripts oder Exportwerkzeugen verarbeiten, können Sie diese sicher verwenden.

0
kepes

Warum nicht den Code von phpMyAdmin nehmen und diesen verwenden? Es ist immerhin Open Source ...

0
Mez

das hat tatsächlich für mich 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;
}
?>
0
canoodle

Ich habe festgestellt, dass der PostgreSQL PDO-Treiber das Ausführen von Skripts, die durch Semikolons getrennt sind, nicht zulässt. Um eine .sql-Datei in einer beliebigen Datenbank mit PDO auszuführen, müssen Sie die Anweisungen im Code PHP selbst aufteilen. Hier ist eine Lösung, die recht gut zu funktionieren scheint:

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

Die referenzierte Klasse hat den Trick auf datenbankunabhängige Art für mich erledigt. Bitte senden Sie mir eine Nachricht, wenn Probleme auftreten. So können Sie das Skript verwenden, nachdem Sie es zu Ihrem Projekt hinzugefügt haben:

$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();
    }
}
0
Dion Truter

Ich hoffe, der folgende Code wird Ihr 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 = '';
}
}

?>
0
Vijin Paulraj

Ich benutze das die ganze Zeit:

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

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