Вопрос

Я создаю сценарий установки для приложения, которое я разрабатываю, и мне нужно динамически создавать базы данных из PHP.У меня есть возможность создать базу данных, но теперь мне нужно загрузить несколько файлов .sql.Я планировал открыть файл и выполнять mysql_query построчно, пока не посмотрел на файлы схемы и не понял, что это не просто один запрос на строку.

Итак, как мне загрузить файл sql из PHP (как это делает phpMyAdmin с помощью команды импорта)?

Это было полезно?

Решение

У меня такое ощущение, что все, кто ответил на этот вопрос, не знают, что значит быть разработчиком веб-приложений, который позволяет людям устанавливать приложения на свои собственные серверы.В частности, общий хостинг не позволяет использовать SQL, например, запрос «LOAD DATA», упомянутый ранее.Большинство общих хостов также не позволяют использовать Shell_exec.

Теперь, чтобы ответить на ОП, лучше всего просто создать файл PHP, который содержит ваши запросы в переменной и может просто запускать их.Если вы полны решимости анализировать файлы .sql, вам следует заглянуть в phpMyAdmin и почерпнуть несколько идей по получению данных из файлов .sql таким способом.Посмотрите на другие веб-приложения, у которых есть установщики, и вы увидите, что вместо того, чтобы использовать файлы .sql для своих запросов, они просто упаковывают их в файлы PHP и просто пропускают каждую строку через mysql_query или что-то еще, что им нужно сделать. .

Другие советы

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

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

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

phpBB использует несколько функций для анализа своих файлов.Они довольно хорошо прокомментированы (какое исключение!), поэтому вы можете легко узнать, что они делают (я получил это решение от http://www.frihost.com/forums/vt-8194.html).вот решение, я его много использовал:

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

?>

Самое простое решение — использовать Shell_exec() для запуска клиента MySQL со сценарием SQL в качестве входных данных.Это может работать немного медленнее из-за необходимости разветвления, но вы можете написать код за пару минут, а затем вернуться к работе над чем-то полезным.Написание PHP-скрипта для запуска любого SQL-скрипта может занять несколько недель.

Поддержка сценариев SQL более сложна, чем то, что здесь описывают, если только вы не уверены, что ваш сценарий содержит только подмножество функций сценариев.Ниже приведены некоторые примеры вещей, которые могут появиться в обычном SQL-скрипте, что усложняет кодирование сценария для его построчной интерпретации.

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

Если вы поддерживаете только подмножество сценариев SQL, исключая некоторые крайние случаи, подобные приведенным выше, относительно легко написать сценарий PHP, который читает файл и выполняет инструкции SQL в файле.Но если вы хотите поддерживать любой действительный сценарий SQL, это гораздо сложнее.


Смотрите также мои ответы на эти связанные вопросы:

mysqli может запускать несколько запросов, разделенных ;

вы можете прочитать весь файл и запустить его сразу, используя mysqli_multi_query()

Но я буду первым, кто скажет, что это не самое элегантное решение.

В своих проектах я использовал следующее решение:

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

При тестовом файле sql (41 МБ) пиковое использование памяти:3,25 МБ

Поскольку я не могу комментировать ответ, остерегайтесь использовать следующее решение:

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

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

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

В PHP PDO есть ошибка. https://bugs.php.net/bug.php?id=61613

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

не выдает ошибку и не возвращает false (проверено на PHP 5.5.14).

Я бы посоветовал посмотреть исходный код PHPMyBackup.Это автоматический загрузчик PHP SQL.Вы обнаружите, что mysql_query загружает только один запрос за раз, а такие проекты, как PHPMyAdmin и PHPMyBackup, уже проделали за вас тяжелую работу по правильному анализу SQL.Пожалуйста, не изобретайте заново этот велосипед :P

Обновленное решение Плачинского.В качестве альтернативы вы можете использовать fopen и fread для файлов большего размера:

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

Вы уверены, что это не один запрос в строке?Ваш текстовый редактор может переносить строки, но на самом деле каждый запрос может содержать одну строку.

В любом случае, метод Олле кажется лучшим.Если у вас есть причины запускать запросы по одному, вы должны иметь возможность читать файл построчно, а затем использовать точку с запятой в конце каждого запроса для разделения.Гораздо лучше читать файл построчно, чем пытаться разбить огромную строку, поскольку это будет намного бережнее для памяти вашего сервера.Пример:

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

Очевидно, вам придется учитывать транзакции и все остальное, если вы выполняете много запросов в пакетном режиме, но это, вероятно, не имеет большого значения для сценария новой установки.

Работает на дампах Navicat.Возможно, придется сбросить первый /* */ комментарий, вставленный 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 = "";
    }
  }
 }

Попробуй это:

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

Вкратце, как я это сделал:

  1. Прочитайте файл (дамп БД, например $ mysqldump db > db.sql)

    $sql = file_get_contents(db.sql);
    
  2. Импортируйте его с помощью mysqli::multi_query.

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

Будьте осторожны, mysqli_query поддерживает асинхронные запросы.Подробнее здесь: http://php.net/manual/en/mysqli.multi-query.php и здесь https://stackoverflow.com/a/6652908/2002493

Если вы не планируете импортировать огромный .sql, просто прочитайте весь файл в памяти и запустите его как запрос.

Давно я не использовал PHP, поэтому псевдокод:

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

Если файлы не огромны (скажем, более нескольких мегабайт), нет смысла выполнять их построчно или пытаться разделить их на несколько запросов (путем разделения с помощью ;, который, как я прокомментировал ответ cam8001, сломается, если в строке запроса есть точки с запятой).

Этот лучший код для восстановления sql с помощью php можно использовать на 100% Goooood!Большое спасибо

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

Самый простой и быстрый способ загрузить и проанализировать дамп phpmyadmin или файл дампа MySQL.

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

Я заметил, что PDO-драйвер PostgreSQL не позволяет запускать скрипты, разделенные точкой с запятой.Чтобы запустить файл .sql в любой базе данных с использованием PDO, необходимо самостоятельно разделить операторы в коде PHP.Вот решение, которое, кажется, работает довольно хорошо:

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

Упомянутый класс помог мне независимо от базы данных. Если возникнут какие-либо проблемы, сообщите мне.Вот как вы можете использовать скрипт после добавления его в свой проект:

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

Ни одно из решений, которые я видел здесь, не связано с необходимостью изменения разделителя при создании хранимой процедуры на сервере, где я не могу рассчитывать на доступ к LOAD DATA INFILE.Я надеялся обнаружить, что кто-то уже решил эту проблему, без необходимости просматривать код phpMyAdmin, чтобы понять это.Как и другие, я тоже искал чей-то способ сделать это под лицензией GPL, поскольку сам пишу код под лицензией GPL.

Некоторые библиотеки PHP могут анализировать файл SQL, состоящий из нескольких операторов SQL, правильно разбивать его (разумеется, без использования простого «;» разрыва) и выполнять их.

Например, проверьте Пинг's PDOSQLExecTask

Просто повторю проблему для всех:

PHP mysql_query автоматически разделяет концы каждой команды SQL, и, кроме того, в руководстве очень расплывчато об этом говорится.Все, что выходит за рамки одной команды, приведет к ошибке.

С другой стороны, mysql_query работает со строкой, содержащей комментарии в стиле SQL, , ..

Ограничение mysql_query проявляется в том, что анализатор SQL сообщает о проблеме непосредственно при следующей команде, например.

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

Вот быстрое решение:(при условии, что SQL правильно отформатирован;

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

Многие хосты не позволят вам создать собственную базу данных через PHP, но вы, похоже, решили эту проблему.
После создания БД вы можете просто манипулировать ею и заполнять ее:

mysql_connect("локальный хост");
mysql_query("ИСХОДНЫЙ файл.sql");

Некоторые ребята (Плачински) предложили этот код:

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

но я бы обновил его тем, который мне помог:

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

потому что оно более всеобъемлющее.;-)

Это может быть полезно -->

Более или менее то, что он делает, это сначала взять строку, переданную функции (значение file_get_contents() вашего файла file.sql) и удалить все разрывы строк.Затем он расщепляет данные на «;» характер.Затем он переходит в цикл while, просматривая каждую строку созданного массива.Если строка содержит символ « ` », он будет знать, что это запрос, и выполнит функцию myquery() для данных данной строки.

Код:

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

Почему бы не взять код из phpMyAdmin и не использовать его?В конце концов, это открытый исходный код...

Я использую это все время:

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

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

Я надеюсь, что следующий код хорошо решит вашу проблему.

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

?>

это действительно сработало для меня:

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

У меня есть среда, в которой нет инструмента MySQL или phpmyadmin, только мое php-приложение, подключающееся к серверу MySQL на другом хосте, но мне нужно запускать сценарии, экспортированные mysqldump или myadmin.Для решения проблемы я создал скрипт multi_query как я уже заметил здесь

Он может обрабатывать вывод mysqldump и экспорт phpmyadmin без инструмента командной строки mysql.Я также разработал некоторую логику для обработки нескольких файлов миграции на основе временной метки, хранящейся в БД, например Rails.Я знаю, что требуется дополнительная обработка ошибок, но в настоящее время все работает за меня.

Проверьте это: https://github.com/kepes/php-migration

Это чистый PHP и не требует никаких других инструментов.Если вы не обрабатываете с его помощью пользовательский ввод, а только скрипты, созданные разработчиками, или инструменты экспорта, вы можете безопасно его использовать.

Это из проекта, над которым я работаю.По сути, берет любой текстовый файл и извлекает операторы SQL, игнорируя комментарии и ненужные разрывы строк.

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

?>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top