Domanda

Sto creando uno script di installazione per un'applicazione che sto sviluppando e ho bisogno di creare database dinamicamente all'interno di PHP. Ce l'ho per creare il database ma ora devo caricare diversi file .sql. Avevo programmato di aprire il file e mysql_query una riga alla volta - fino a quando non ho guardato i file dello schema e ho capito che non sono solo una query per riga.

Quindi, come posso caricare un file sql da PHP (come fa phpMyAdmin con il suo comando di importazione)?

È stato utile?

Soluzione

Ho la sensazione che tutti coloro che hanno risposto a questa domanda non sappiano cosa significhi essere uno sviluppatore di applicazioni web che consente alle persone di installare l'applicazione sui propri server. L'hosting condiviso, in particolare, non ti consente di utilizzare SQL come " LOAD DATA " query menzionata in precedenza. La maggior parte degli host condivisi non consente inoltre di utilizzare shell_exec.

Ora, per rispondere al PO, la soluzione migliore è semplicemente creare un file PHP che contenga le tue query in una variabile e che possa semplicemente eseguirle. Se sei determinato ad analizzare i file .sql, dovresti esaminare phpMyAdmin e ottenere alcune idee per ottenere i dati dai file .sql in quel modo. Guarda le altre applicazioni web che hanno programmi di installazione e vedrai che, invece di utilizzare i file .sql per le loro query, li impacchettano semplicemente in file PHP ed eseguono ogni stringa attraverso mysql_query o qualunque altra cosa debbano fare .

Altri suggerimenti

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

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

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

phpBB usa alcune funzioni per analizzare i loro file. Sono piuttosto ben commentati (che eccezione!), Quindi puoi facilmente sapere cosa fanno (ho ottenuto questa soluzione da http://www.frihost.com/forums/vt-8194.html ). ecco la soluzione e l'ho usata molto:

<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');
}

?>

La soluzione più semplice è usare shell_exec () per eseguire il client mysql con lo script SQL come input. Questo potrebbe essere un po 'più lento perché deve essere fork, ma puoi scrivere il codice in un paio di minuti e poi tornare a lavorare su qualcosa di utile. Scrivere uno script PHP per eseguire qualsiasi script SQL potrebbe richiedere settimane.

Il supporto degli script SQL è più complesso di quello che le persone descrivono qui, a meno che non si sia certi che lo script contenga solo un sottoinsieme delle funzionalità degli script. Di seguito sono riportati alcuni esempi di cose che possono apparire in un normale script SQL che rendono complicato codificare uno script per interpretarlo riga per riga.

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

Se si supporta solo un sottoinsieme di script SQL, esclusi alcuni casi angolari come quelli sopra, è relativamente facile scrivere uno script PHP che legge un file ed esegue le istruzioni SQL all'interno del file. Ma se vuoi supportare uno script SQL valido, è molto più complesso.


Vedi anche le mie risposte a queste domande correlate:

mysqli può eseguire più query separate da un ;

puoi leggere l'intero file ed eseguirlo tutto in una volta usando mysqli_multi_query ()

Ma sarò il primo a dire che questa non è la soluzione più elegante.

Nei miei progetti ho usato la soluzione successiva:

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

Su utilizzo del picco di memoria del file sql di prova (41Mb): 3.25Mb

Poiché non posso commentare la risposta, fai attenzione a utilizzare la seguente soluzione:

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

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

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

C'è un bug in PHP DOP https://bugs.php.net/bug .php? id = 61613

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

non genererà errori o restituirà false (testato su PHP 5.5.14).

Il mio suggerimento sarebbe di guardare il codice sorgente di PHPMyBackup. È un caricatore SQL PHP automatizzato. Scoprirai che mysql_query carica solo una query alla volta e progetti come PHPMyAdmin e PHPMyBackup hanno già fatto il duro lavoro per te nell'analisi dell'SQL nel modo corretto. Per favore, non reinventare quella ruota: P

Una soluzione aggiornata della soluzione Plahcinski. In alternativa puoi usare fopen e fread per file più grandi:

$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 = '';
        }
    }
}

Sei sicuro che non sia una query per riga? Il tuo editor di testo potrebbe essere a capo di righe, ma in realtà ogni query può trovarsi su una sola riga.

Ad ogni modo, il metodo di olle sembra il migliore. Se hai motivi per eseguire le query una alla volta, dovresti essere in grado di leggere il file riga per riga, quindi utilizzare il punto e virgola alla fine di ogni query per delimitare. Stai molto meglio leggere in un file riga per riga piuttosto che cercare di dividere un'enorme stringa, poiché sarà molto più gentile con la memoria del tuo server. Esempio:

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

Ovviamente, dovrai considerare le transazioni e il resto se esegui molte query in un batch, ma probabilmente non è un grosso problema per uno script di nuova installazione.

Funziona su dump Navicat. Potrebbe essere necessario scaricare il primo / * * / commento inserito da navicat.

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

Prova questo:

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

In breve, il modo in cui l'ho fatto è:

  1. Leggi il file (una discarica db, ad esempio $ mysqldump db > db.sql )

    $sql = file_get_contents(db.sql);
    
  2. Importalo usando mysqli :: multi_query

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

Attenzione mysqli_query supporta query asincrone. Altro qui: http://php.net/manual/en/mysqli.multi -query.php e qui https://stackoverflow.com/a/6652908/2002493

A meno che tu non preveda di importare enormi file .sql, leggi l'intero file in memoria ed eseguilo come query.

È da un po 'che non uso PHP, quindi pseudo codice:

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

A meno che i file non siano enormi (diciamo, su diversi megabyte), non c'è motivo di eseguirlo riga per volta o provare a dividerlo in più query (suddividendo utilizzando ; , che come ho commentato sulla risposta di cam8001, si interromperà se la query contiene punti e virgola all'interno di stringhe).

Questo Il miglior codice per ripristinare sql da php può usare Goooood al 100%!  Grazie mille

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

Il modo più semplice e veloce per caricare & amp; analizzare il dump di phpmyadmin o il file di dump mysql ..

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

Ho notato che il driver PostgreSQL PDO non consente di eseguire script separati da punti e virgola. Per eseguire un file .sql su qualsiasi database utilizzando PDO è necessario dividere le istruzioni nel codice PHP. Ecco una soluzione che sembra funzionare abbastanza bene:

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

La classe di riferimento ha fatto il trucco per me in modo indipendente dal database, per favore inviami un messaggio se ci sono problemi. Ecco come potresti usare lo script dopo averlo aggiunto al tuo progetto:

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

Nessuna delle soluzioni che ho visto qui riguarda la necessità di cambiare il delimitatore durante la creazione di una procedura memorizzata su un server in cui non posso contare sull'accesso a LOAD DATA INFILE. Speravo di scoprire che qualcuno aveva già risolto questo problema senza dover sgridare il codice phpMyAdmin per capirlo. Come altri, anch'io ero in procinto di cercare il modo GPL di qualcun altro per farlo da quando scrivo il codice GPL da solo.

Alcune librerie PHP possono analizzare un file SQL composto da più istruzioni SQL, esplodere correttamente (non usando un semplice "esplodere", naturalmente) ed eseguirle.

Ad esempio, controlla Phing 's PDOSQLExecTask

Solo per riaffermare il problema per tutti:

mysql_query di PHP, delimita automaticamente ogni comando SQL e inoltre è molto vago nel farlo nel suo manuale. Tutto al di là di un comando produrrà un errore.

D'altra parte mysql_query va bene con una stringa contenente commenti in stile SQL, \ n, \ r ..

La limitazione di mysql_query si rivela in quanto il parser SQL segnala che il problema è direttamente al comando successivo, ad es.

 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...

Ecco una soluzione rapida: (supponendo che SQL ben formattato;

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

Molti host non ti permetteranno di creare il tuo database tramite PHP, ma sembra che tu l'abbia risolto.
Una volta creato il DB, puoi manipolarlo e popolarlo semplicemente:

  

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

Alcuni ragazzi (Plahcinski) hanno suggerito questo codice:

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

ma lo aggiornerei con quello che ha funzionato per me:

 //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 = "";
            }
          }
         }

perché è più completo. ; -)

Potrebbe essere utile - >

Più o meno ciò che fa è prendere prima la stringa data alla funzione (il valore file_get_contents () del tuo file.sql) e rimuovere tutte le interruzioni di riga. Quindi divide i dati per "quot"; " personaggio. Successivamente passa a un ciclo while, guardando ogni riga dell'array che viene creato. Se la riga contiene " `" carattere, saprà che è una query ed esplora la funzione myquery () per i dati della riga dati.

Codice:

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

Perché non prendere il codice da phpMyAdmin e usarlo? Dopo tutto è Open Source ...

Lo uso sempre:

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

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

Spero che il seguente codice risolva abbastanza bene il tuo problema.
    

//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 = '';
}
}

?>

questo effettivamente ha funzionato per me:

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

Ho un ambiente in cui nessuno strumento mysql o phpmyadmin è solo la mia applicazione php che si collega a un server mysql su un host diverso ma devo eseguire gli script esportati da mysqldump o myadmin. Per risolvere il problema ho creato uno script multi_query come ho detto qui

Può elaborare l'output di mysqldump e le esportazioni phpmyadmin senza lo strumento da riga di comando mysql. Ho anche creato un po 'di logica per elaborare più file di migrazione in base al timestamp archiviato in DB come Rails. So che ha bisogno di più gestione degli errori, ma al momento fa il lavoro per me.

Dai un'occhiata: https://github.com/kepes/php-migration

È puro php e non necessita di altri strumenti. Se non elabori l'input dell'utente con esso solo script creati da sviluppatori o strumenti di esportazione, puoi utilizzarlo in modo sicuro.

Questo proviene da un progetto a cui sto lavorando. Praticamente prende qualsiasi file di testo ed estrae le istruzioni SQL ignorando i commenti e le interruzioni di riga gratuite.

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

?>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top