Question

Je crée un script d'installation pour une application que je développe et j'ai besoin de créer des bases de données de manière dynamique à partir de PHP. Je l'ai pour créer la base de données, mais je dois maintenant charger plusieurs fichiers .sql. J'avais prévu d'ouvrir le fichier mysql_query, une ligne à la fois, jusqu'à ce que j'examine les fichiers de schéma et que je réalise qu'ils ne sont pas une requête par ligne.

Alors, comment puis-je charger un fichier SQL depuis PHP (comme le fait phpMyAdmin avec sa commande d'importation)?

Était-ce utile?

La solution

J'ai l'impression que tous ceux qui ont répondu à cette question ne savent pas ce que c'est que d'être un développeur d'applications Web qui permet aux gens d'installer l'application sur leurs propres serveurs. L'hébergement partagé, en particulier, ne vous permet pas d'utiliser SQL comme "LOAD DATA". requête mentionnée précédemment. La plupart des hôtes partagés ne vous autorisent pas non plus à utiliser shell_exec.

Maintenant, pour répondre au PO, votre meilleur choix est de créer un fichier PHP contenant vos requêtes dans une variable et de les exécuter. Si vous êtes déterminé à analyser les fichiers .sql, vous devriez jeter un œil sur phpMyAdmin et trouver des idées pour extraire les données des fichiers .sql de cette façon. Regardez autour de vous avec d'autres applications Web qui ont des installateurs et vous verrez que, plutôt que d'utiliser des fichiers .sql pour leurs requêtes, ils les empaquetent dans des fichiers PHP et exécutent chaque chaîne via mysql_query ou tout ce dont ils ont besoin. .

Autres conseils

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

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

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

phpBB utilise quelques fonctions pour analyser leurs fichiers. Ils sont plutôt bien commentés (quelle exception!) Et vous pouvez donc facilement savoir ce qu'ils font (j'ai obtenu cette solution auprès de http://www.frihost.com/forums/vt-8194.html ). voici la solution et je l'ai beaucoup utilisée:

<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 solution la plus simple consiste à utiliser shell_exec () pour exécuter le client mysql avec le script SQL en entrée. Cela peut être un peu plus lent, car il doit être modifié, mais vous pouvez écrire le code en quelques minutes, puis reprendre votre travail. L'écriture d'un script PHP pour exécuter n'importe quel script SQL peut prendre des semaines.

La prise en charge des scripts SQL est plus complexe que ce que les gens décrivent ici, sauf si vous êtes certain que votre script ne contient qu'un sous-ensemble de ses fonctionnalités. Vous trouverez ci-dessous quelques exemples d'éléments susceptibles d'apparaître dans un script SQL ordinaire et rendant complexe le codage d'un script afin de l'interpréter ligne par ligne.

-- 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 vous ne prenez en charge qu'un sous-ensemble de scripts SQL, à l'exception de certains cas tels que ceux décrits ci-dessus, il est relativement facile d'écrire un script PHP qui lit un fichier et exécute les instructions SQL qu'il contient. Mais si vous voulez supporter un script SQL valide, c'est beaucoup plus complexe.

Voir aussi mes réponses aux questions suivantes:

mysqli peut exécuter plusieurs requêtes séparées par un ;

vous pouvez lire l'intégralité du fichier et l'exécuter en une seule fois à l'aide de mysqli_multi_query ()

Mais je serai le premier à dire que ce n'est pas la solution la plus élégante.

Dans mes projets, j'ai utilisé la solution suivante:

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

Utilisation maximale de mémoire au cours du test du fichier SQL (41 Mo): 3,25 Mo

Comme je ne peux pas commenter la réponse, prenez garde à utiliser la solution suivante:

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

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

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

Il y a un bogue dans le PDO PHP https://bugs.php.net/bug .php? id = 61613

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

ne générera pas d'erreur ni ne retournera false (testé sur PHP 5.5.14).

Ma suggestion serait de consulter le code source de PHPMyBackup. C'est un chargeur automatique de PHP PHP. Vous constaterez que mysql_query ne charge qu'une requête à la fois, et des projets tels que PHPMyAdmin et PHPMyBackup ont déjà fait le travail difficile pour vous d’analyser correctement le code SQL. S'il vous plaît ne réinventez pas cette roue: P

Une solution mise à jour de la solution Plahcinski. Vous pouvez également utiliser fopen et fread pour les fichiers plus volumineux:

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

Êtes-vous sûr que ce n'est pas une requête par ligne? Votre éditeur de texte est peut-être un saut de ligne, mais en réalité, chaque requête peut être sur une seule ligne.

Quoi qu’il en soit, la méthode d’Olle semble la meilleure. Si vous avez des raisons d'exécuter des requêtes une par une, vous devriez pouvoir lire votre fichier ligne par ligne, puis utiliser le point-virgule à la fin de chaque requête pour délimiter. Vous feriez bien mieux de lire dans un fichier ligne par ligne plutôt que d'essayer de scinder une énorme chaîne, car cela serait beaucoup plus gentil pour la mémoire de votre serveur. Exemple:

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

Évidemment, vous devrez prendre en compte les transactions et le reste si vous exécutez un grand nombre de requêtes dans un lot, mais ce n'est probablement pas une grosse affaire pour un nouveau script d'installation.

Fonctionne sur les décharges Navicat. Peut-être besoin de vider le premier / * * / commentaire que navicat met dedans.

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

Essayez ceci:

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

En bref, voici comment je l’ai fait:

  1. Lisez le fichier (un dump, par exemple, $ mysqldump db > db.sql )

    .
    $sql = file_get_contents(db.sql);
    
  2. Importez-le en utilisant mysqli :: multi_query

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

Attention, mysqli_query prend en charge les requêtes asynchrones. Plus ici: http://php.net/manual/fr/mysqli.multi -query.php et ici https://stackoverflow.com/a/6652908/2002493

Sauf si vous envisagez d'importer d’énormes fichiers .sql, il vous suffit de lire l’ensemble du fichier en mémoire et de l’exécuter en tant que requête.

Cela fait longtemps que je n’utilise pas PHP, donc 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()

À moins que les fichiers soient volumineux (par exemple, sur plusieurs mégaoctets), il n'y a aucune raison de l'exécuter ligne par ligne ou d'essayer de le scinder en plusieurs requêtes (en scindant avec ; qui, comme je l'ai commenté sur la réponse de cam8001, se cassera si la requête contient des points-virgules dans des chaînes).

This Le meilleur code pour la restauration SQL par PHP peut utiliser 100% Goooood!  Merci beaucoup

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

Le moyen le plus simple et le plus rapide de charger & amp; analyser phpmyadmin dump ou le fichier de vidage mysql.

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

J'ai remarqué que le pilote PDO PostgreSQL ne vous permettait pas d'exécuter des scripts séparés par des points-virgules. Pour pouvoir exécuter un fichier .sql sur une base de données utilisant PDO, il est nécessaire de scinder vous-même les instructions en code PHP. Voici une solution qui semble bien fonctionner:

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

La classe référencée a fait le tour pour moi d'une manière indépendante de la base de données. Veuillez m'envoyer un message en cas de problème. Voici comment utiliser le script après l'avoir ajouté à votre projet:

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

Aucune des solutions évoquées ici ne nécessite de modifier le délimiteur lors de la création d'une procédure stockée sur un serveur où je ne peux pas compter sur l'accès à LOAD DATA INFILE. J'espérais trouver que quelqu'un avait déjà résolu ce problème sans avoir à parcourir le code phpMyAdmin pour le résoudre. Comme d’autres, j’étais moi aussi en train de chercher le moyen de le faire sous licence GPL, car j’écris moi-même le code GPL.

Certaines bibliothèques PHP peuvent analyser un fichier SQL composé de plusieurs instructions SQL, le faire exploser correctement (sans utiliser un simple éclatement "naturellement"), puis les exécuter.

Par exemple, vérifiez les Phing PDOSQLExecTask

Juste pour reformuler le problème pour tout le monde:

La requête mysql_query de PHP, délimite automatiquement chaque commande SQL, et est en outre très vague dans son manuel. Toute commande dépassant une commande générera une erreur.

Par ailleurs, mysql_query convient parfaitement avec une chaîne contenant des commentaires de style SQL, \ n, \ r ..

La limitation de mysql_query se révèle en ce que l'analyseur SQL signale que le problème se trouve directement à la commande suivante, par exemple.

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

Voici une solution rapide: (en supposant que le SQL soit bien formaté;

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

De nombreux hôtes ne vous autoriseront pas à créer votre propre base de données via PHP, mais vous semblez avoir résolu le problème.
Une fois la base de données créée, vous pouvez la manipuler et la renseigner simplement:

  

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

Certains gars (Plahcinski) ont suggéré ce code:

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

mais je voudrais le mettre à jour avec celui qui a fonctionné pour moi:

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

parce que c'est plus complet. ; -)

Cela peut être utile - >

Plus ou moins, il faut d'abord prendre la chaîne donnée à la fonction (la valeur file_get_contents () de votre fichier.sql) et supprimer tous les sauts de ligne. Ensuite, il scinde les données en utilisant le " ;; " personnage. Ensuite, il passe dans une boucle while en regardant chaque ligne du tableau créé. Si la ligne contient le " `" caractère, il saura qu’il s’agit d’une requête et exécutera la fonction myquery () pour les données de ligne données.

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

Pourquoi ne pas prendre le code de phpMyAdmin et l'utiliser? C'est Open Source après tout ...

Je l'utilise tout le temps:

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

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

J'espère que le code suivant résoudra votre problème assez 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 = '';
}
}

?>

cela a réellement fonctionné pour moi:

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

J'ai un environnement dans lequel aucun outil mysql ou phpmyadmin ne concerne que mon application php se connectant à un serveur mysql sur un hôte différent, mais je dois exécuter des scripts exportés par mysqldump ou myadmin. Pour résoudre ce problème, j’ai créé un script multi_query en mentionnant ici

Il peut traiter les sorties mysqldump et les exportations phpmyadmin sans l'outil de ligne de commande mysql. J'ai également créé une logique pour traiter plusieurs fichiers de migration en fonction de l'horodatage stocké dans une base de données telle que Rails. Je sais qu’il faut davantage de traitement des erreurs, mais fait actuellement le travail pour moi.

Découvrez-le: https://github.com/kepes/php-migration

C'est du pur php et vous n'avez pas besoin d'autres outils. Si vous ne traitez pas les entrées utilisateur avec uniquement des scripts créés par des développeurs ou des outils d'exportation, vous pouvez les utiliser en toute sécurité.

Cela provient d'un projet sur lequel je travaille. Prend essentiellement n'importe quel fichier texte et extrait les instructions SQL en ignorant les commentaires et les sauts de ligne gratuits.

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

?>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top