Загрузка файлов .sql из PHP - PullRequest
       149

Загрузка файлов .sql из PHP

62 голосов
/ 29 сентября 2008

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

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

Ответы [ 30 ]

1 голос
/ 19 сентября 2013

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

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

потому что оно более полное. ; -)

1 голос
/ 01 сентября 2010

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

Например, отметьте Phing s PDOSQLExecTask

1 голос
/ 30 января 2017

Я заметил, что драйвер PostgreSQL PDO не позволяет запускать сценарии, разделенные точками с запятой. Чтобы запустить файл .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();
    }
}
1 голос
/ 30 октября 2011

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

mysql_connect ( "локальный");
mysql_query ("SOURCE file.sql");

0 голосов
/ 21 января 2015

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

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

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

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

0 голосов
/ 18 сентября 2013

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

/* load sql-commands from a sql file */
function loadSQLFromFile($url)
{
    // ini_set ( 'memory_limit', '512M' );
    // set_time_limit ( 0 );

    global $settings_database_name;
    global $mysqli_object; global $worked; $worked = false;

    $sql_query = "";

    // read line by line
    $lines = file($url);
    $count = count($lines);

    for($i = 0;$i<$count;$i++)
    {
        $line = $lines[$i];
        $cmd3 = substr($line, 0, 3);
        $cmd4 = substr($line, 0, 4);
        $cmd6 = substr($line, 0, 6);
        if($cmd3 == "USE")
        {
            // cut away USE ``;
            $settings_database_name = substr($line, 5, -3);
        }
        else if($cmd4 == "DROP")
        {
            $mysqli_object->query($line); // execute this line
        }
        else if(($cmd6 == "INSERT") || ($cmd6 == "CREATE"))
        {
            // sum all lines up until ; is detected
            $multiline = $line;
            while(!strstr($line, ';'))
            {
                $i++;
                $line = $lines[$i];
                $multiline .= $line;
            }
            $multiline = str_replace("\n", "", $multiline); // remove newlines/linebreaks
            $mysqli_object->query($multiline); // execute this line
        }       
    }

    return $worked;
}
?>
0 голосов
/ 12 января 2011

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

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

foreach($sql as $query)
 mysql_query($query);
0 голосов
/ 09 января 2012

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

//Empty all tables' contents

$result_t = mysql_query("SHOW TABLES");
while($row = mysql_fetch_assoc($result_t))
{
mysql_query("TRUNCATE " . $row['Tables_in_' . $mysql_database]);
}
// Temporary variable, used to store current query
$templine = '';
// Read in entire file
$lines = file($filename);
// Loop through each line
foreach ($lines as $line)
{
// Skip it if it's a comment
if (substr($line, 0, 2) == '--' || $line == '')
    continue;

// Add this line to the current segment
$templine .= $line;
// If it has a semicolon at the end, it's the end of the query
if (substr(trim($line), -1, 1) == ';')
{
    // Perform the query
    mysql_query($templine) or print('Error performing query \'<strong>' . $templine . '\': ' . mysql_error() . '<br /><br />');
    // Reset temp variable to empty
    $templine = '';
}
}

?>
0 голосов
/ 30 марта 2019

Это из проекта, над которым я работаю. В основном берет любой текстовый файл и извлекает операторы 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;
  }

?>
0 голосов
/ 29 сентября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...