Pregunta

Estoy creando un script de instalación para una aplicación que estoy desarrollando y necesito crear bases de datos dinámicamente desde PHP. Lo tengo para crear la base de datos pero ahora necesito cargar varios archivos .sql. Había planeado abrir el archivo y mysql_query una línea a la vez, hasta que miré los archivos de esquema y me di cuenta de que no son solo una consulta por línea.

Entonces, ¿cómo puedo cargar un archivo SQL desde PHP (como hace phpMyAdmin con su comando de importación)?

¿Fue útil?

Solución

Tengo la sensación de que todos los que respondieron a esta pregunta no saben lo que es ser un desarrollador de aplicaciones web que les permite a las personas instalar la aplicación en sus propios servidores. El alojamiento compartido, especialmente, no le permite usar SQL como el " LOAD DATA " consulta mencionada anteriormente. La mayoría de los hosts compartidos tampoco le permiten usar shell_exec.

Ahora, para responder al OP, lo mejor es construir un archivo PHP que contenga sus consultas en una variable y pueda ejecutarlas. Si está decidido a analizar los archivos .sql, debe buscar en phpMyAdmin y obtener algunas ideas para obtener datos de los archivos .sql de esa manera. Mire a su alrededor otras aplicaciones web que tienen instaladores y verá que, en lugar de usar archivos .sql para sus consultas, simplemente los empaquetan en archivos PHP y simplemente ejecutan cada cadena a través de mysql_query o lo que sea que necesiten hacer. .

Otros consejos

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

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

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

phpBB usa algunas funciones para analizar sus archivos. Están bastante bien comentados (¡qué excepción!) Para que pueda saber fácilmente lo que hacen (obtuve esta solución de http://www.frihost.com/forums/vt-8194.html ). Aquí está la solución y la he usado mucho:

<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 solución más simple es usar shell_exec () para ejecutar el cliente mysql con el script SQL como entrada. Esto podría correr un poco más lento porque tiene que bifurcarse, pero puede escribir el código en un par de minutos y luego volver a trabajar en algo útil. Escribir un script PHP para ejecutar cualquier script SQL puede llevarte semanas.

El soporte de scripts SQL es más complejo que lo que la gente describe aquí, a menos que esté seguro de que su script contiene solo un subconjunto de la funcionalidad de los scripts. A continuación se presentan algunos ejemplos de cosas que pueden aparecer en un script SQL ordinario que hacen que sea complejo codificar un script para interpretarlo línea por línea.

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

Si solo admite un subconjunto de scripts SQL, excluyendo algunos casos de esquina como los anteriores, es relativamente fácil escribir un script PHP que lea un archivo y ejecute las declaraciones SQL dentro del archivo. Pero si desea admitir cualquier script SQL válido, eso es mucho más complejo.


Vea también mis respuestas a estas preguntas relacionadas:

mysqli puede ejecutar varias consultas separadas por un ;

puede leer todo el archivo y ejecutarlo todo a la vez utilizando mysqli_multi_query ()

Pero, seré el primero en decir que esta no es la solución más elegante.

En mis proyectos he usado la siguiente solución:

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

En uso máximo de memoria de archivo de prueba sql (41Mb): 3.25Mb

Ya que no puedo comentar la respuesta, tenga cuidado de usar la siguiente solución:

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

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

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

Hay un error en PHP DOP https://bugs.php.net/bug .php? id = 61613

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

no generará errores o devolverá falso (probado en PHP 5.5.14).

Mi sugerencia sería mirar el código fuente de PHPMyBackup. Es un cargador de PHP SQL automatizado. Encontrará que mysql_query solo carga una consulta a la vez, y proyectos como PHPMyAdmin y PHPMyBackup ya han hecho el trabajo duro para que analice el SQL de la manera correcta. Por favor, no reinventes esa rueda: P

Una solución actualizada de la solución Plahcinski. Alternativamente, puede usar fopen y fread para archivos más grandes:

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

¿Está seguro de que no es una consulta por línea? Su editor de texto puede estar ajustando líneas, pero en realidad cada consulta puede estar en una sola línea.

En cualquier caso, el método de olle parece mejor. Si tiene motivos para ejecutar consultas una por una, debería poder leer en su archivo línea por línea y luego usar el punto y coma al final de cada consulta para delimitar. Es mucho mejor leer un archivo línea por línea que tratar de dividir una cadena enorme, ya que será mucho más amable con la memoria de su servidor. Ejemplo:

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

Obviamente, necesitará considerar las transacciones y el resto si está ejecutando muchas consultas en un lote, pero probablemente no sea un gran problema para un script de nueva instalación.

Funciona en volcados de Navicat. Es posible que tenga que volcar los primeros / * * / comentarios de 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 = "";
    }
  }
 }

Prueba esto:

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

Brevemente, la forma en que lo hice es:

  1. Lea el archivo (un volcado de base de datos, por ejemplo, $ mysqldump db > db.sql )

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

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

Tenga cuidado mysqli_query admite consultas asíncronas. Más aquí: http://php.net/manual/en/mysqli.multi -query.php y aquí https://stackoverflow.com/a/6652908/2002493

A menos que planee importar archivos enormes .sql, simplemente lea todo el archivo en la memoria y ejecútelo como una consulta.

Ha pasado un tiempo desde que usé PHP, entonces, pseudocódigo:

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

A menos que los archivos sean enormes (por ejemplo, en varios megabytes), no hay razón para ejecutarlos línea por vez, o intentar dividirlos en múltiples consultas (dividiéndolos usando ; , que como comenté en la respuesta de cam8001, se romperá si la consulta tiene punto y coma entre cadenas) ..

Este El mejor código para restaurar sql por php puede usar 100% Goooood!  Muchas gracias

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

La forma más fácil y rápida de cargar & amp; analizar phpmyadmin dump o mysql dump file ..

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

Noté que el controlador PDO PostgreSQL no le permite ejecutar scripts separados por punto y coma. Para ejecutar un archivo .sql en cualquier base de datos usando PDO, es necesario dividir las declaraciones en el código PHP usted mismo. Aquí hay una solución que parece funcionar bastante bien:

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

La clase referenciada ha hecho el truco para mí de una manera independiente de la base de datos, por favor envíeme un mensaje si hay algún problema. Aquí es cómo puede usar el script después de agregarlo a su proyecto:

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

Ninguna de las soluciones que he visto aquí tiene que ver con la necesidad de cambiar el delimitador al crear un procedimiento almacenado en un servidor donde no puedo contar con tener acceso a LOAD DATA INFILE. Esperaba encontrar que alguien ya hubiera resuelto esto sin tener que rastrear el código phpMyAdmin para averiguarlo. Al igual que otros, yo también estaba en el proceso de buscar la manera de hacerlo de la GPL de otra persona, ya que yo mismo estoy escribiendo el código de la GPL.

Algunas bibliotecas PHP pueden analizar un archivo SQL hecho de múltiples sentencias SQL, explotarlo correctamente (sin usar un simple "explotar", naturalmente) y ejecutarlo.

Por ejemplo, marque Phing 's PDOSQLExecTask

Solo para repetir el problema para todos:

MySql_query de PHP, delimita automáticamente cada comando SQL, y además es muy vago al hacerlo en su manual. Todo más allá de un comando producirá un error.

En el otro mysql_query está bien con una cadena que contiene comentarios de estilo SQL, \ n, \ r ..

La limitación de mysql_query se revela en que el analizador SQL informa que el problema está directamente en el siguiente comando, por ejemplo,

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

Aquí hay una solución rápida: (asumiendo un SQL bien formateado;

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

Muchos hosts no le permitirán crear su propia base de datos a través de PHP, pero parece que lo ha resuelto.
Una vez que se ha creado la base de datos, puede manipularla y completarla simplemente:

  

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

Algunos chicos (Plahcinski) sugirieron este código:

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

pero lo actualizaría con el que funcionó para mí:

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

porque es más completo. ;-)

Esto puede ser útil - >

Más o menos lo que hace es tomar primero la cadena dada a la función (el valor file_get_contents () de su file.sql) y eliminar todos los saltos de línea. Luego divide los datos por " ;; " personaje. A continuación, entra en un ciclo while, mirando cada línea de la matriz que se crea. Si la línea contiene el " `" carácter, sabrá que es una consulta y ejecutará la función myquery () para los datos de línea dados.

Código:

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

¿Por qué no tomar el código de phpMyAdmin y usarlo? Es de código abierto después de todo ...

Uso esto todo el tiempo:

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

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

Espero que el siguiente código resuelva tu problema bastante bien.
    

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

?>

esto realmente funcionó para mí:

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

Tengo un entorno donde ninguna herramienta mysql o phpmyadmin solo mi aplicación php se conecta a un servidor mysql en un host diferente, pero necesito ejecutar scripts exportados por mysqldump o myadmin. Para resolver el problema, creé un script multi_query como mencioné here

Puede procesar las salidas de mysqldump y las exportaciones de phpmyadmin sin la herramienta de línea de comandos mysql. También hice algo de lógica para procesar múltiples archivos de migración basados ??en la marca de tiempo almacenada en DB como Rails. Sé que necesita más manejo de errores, pero actualmente hace el trabajo por mí.

Compruébalo: https://github.com/kepes/php-migration

Es php puro y no necesita ninguna otra herramienta. Si no procesa las entradas del usuario con solo scripts creados por desarrolladores o herramientas de exportación, puede usarlos de forma segura.

Esto es de un proyecto en el que estoy trabajando. Básicamente toma cualquier archivo de texto y extrae las declaraciones SQL mientras ignora los comentarios y los saltos de línea gratuitos.

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

?>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top