質問

開発中のアプリケーションのインストール スクリプトを作成しており、PHP 内からデータベースを動的に作成する必要があります。データベースを作成することができましたが、次にいくつかの .sql ファイルをロードする必要があります。ファイルを開いて、一度に 1 行ずつ mysql_query を実行する予定でしたが、スキーマ ファイルを見て、1 行に 1 つのクエリだけではないことに気づきました。

では、PHP 内から SQL ファイルをロードするにはどうすればよいでしょうか (phpMyAdmin が import コマンドで行うように)。

役に立ちましたか?

解決

この質問に答えた誰もが、自分のサーバーにアプリケーションをインストールすることを許可するWebアプリケーション開発者であるとはどういうことか知らないように感じています。特に、共有ホスティングでは、" LOAD DATA"のようなSQLを使用できません。前述のクエリ。ほとんどの共有ホストでは、shell_execの使用も許可されていません。

今、OPに答えるために、あなたの最善の策は、変数にクエリを含み、それらを実行できるPHPファイルを構築することです。 .sqlファイルを解析することに決めた場合は、phpMyAdminを調べ、そのようにして.sqlファイルからデータを取得するためのアイデアを得る必要があります。インストーラーを備えた他のWebアプリケーションを見てみると、クエリに.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()を使用して、入力としてSQLスクリプトを使用してmysqlクライアントを実行することです。フォークする必要があるため、これは少し遅くなる可能性がありますが、数分でコードを記述してから有用な作業に戻ることができます。 PHPスクリプトを記述してSQLスクリプトを実行するには、数週間かかる場合があります。

SQLスクリプトのサポートは、スクリプトにスクリプトの機能のサブセットのみが含まれていることが確実でない限り、ここで説明しているものよりも複雑です。以下に、通常のSQLスクリプトに表示される可能性のあるいくつかの例を示します。これにより、スクリプトを1行ずつ解釈するようにコーディングすることが複雑になります。

-- 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スクリプトのサブセットのみをサポートし、上記のようないくつかのコーナーケースを除外する場合、ファイルを読み取り、ファイル内のSQLステートメントを実行するPHPスクリプトを作成するのは比較的簡単です。ただし、有効な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ファイル(41Mb)のメモリピーク使用量:3.25Mb

回答についてコメントできないため、次の解決策を使用するように注意してください:

$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は一度に1つのクエリのみをロードし、PHPMyAdminやPHPMyBackupのようなプロジェクトはSQLを正しい方法で解析するためのハードワークをすでに行っていることがわかります。その車輪を再発明しないでください:P

Plahcinskiソリューションの更新されたソリューション。または、大きなファイルに対して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 = '';
        }
    }
}

1行に1つのクエリではないことを確認していますか?テキストエディターは行を折り返している場合がありますが、実際には各クエリは1行になっている場合があります。

とにかく、olleの方法が最適のようです。クエリを1つずつ実行する理由がある場合は、ファイルを1行ずつ読み取ってから、各クエリの最後にセミコロンを使用して区切ります。巨大な文字列を分割しようとするよりも、サーバーのメモリにはるかに優しいので、ファイルを1行ずつ読み込む方がはるかに優れています。例:

$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. ファイルを読み取ります(dbダンプ、たとえば $ mysqldump db&gt; 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()

ファイルが巨大(たとえば、数メガバイト以上)でない限り、一度に1行ずつ実行したり、; を使用して複数のクエリに分割したりする理由はありません。 、これはcam8001の答えについてコメントしたように、クエリの文字列内にセミコロンが含まれていると壊れます)。

これは、PHPによるSQLの復元に最適なコードです。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 = "";
  }
 }
}

&amp;をロードする最も簡単で最速の方法phpmyadminダンプまたはmysqlダンプファイルを解析します。.

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

PostgreSQL PDOドライバーでは、セミコロンで区切られたスクリプトを実行できないことに気付きました。 PDOを使用して任意のデータベースで.sqlファイルを実行するには、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 ファイルを解析し、適切に展開し (当然、単純な ";" 展開は使用しません)、それらを実行できます。

たとえば、チェックしてください ピンさんの PDOSQLExecタスク

すべての人のために問題を再度述べます:

PHPのmysql_queryは、各SQLコマンドの末尾を自動的に区切ります。さらに、マニュアルではそうすることについて非常にあいまいです。 1つのコマンドを超えるものはすべてエラーになります。

他のmysql_queryでは、SQLスタイルのコメント、\ n、\ r ..を含む文字列で問題ありません。

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を使用して独自のデータベースを作成することはできませんが、それを解決したようです。
DBが作成されたら、簡単に操作してデータを追加できます。

  

mysql_connect(&quot; localhost&quot;);
  mysql_query(&quot; SOURCE file.sql&quot;);

一部の人(Plahcinski)はこのコードを提案しました:

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

より包括的なため。 ;-)

これは役に立つかもしれません-&gt;

多かれ少なかれ、関数に与えられた文字列(file.sqlのfile_get_contents()値)を最初に取得し、すべての改行を削除することです。次に、データを&quot ;;&quot;で分割します。キャラクター。次に、whileループに入り、作成された配列の各行を調べます。行に&quot;が含まれている場合`&quot;文字、それがクエリであることを認識し、指定された行データの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が別のホスト上のmysqlサーバーに接続するだけのphpアプリケーションがない環境がありますが、mysqldumpまたはmyadminによってエクスポートされたスクリプトを実行する必要があります。この問題を解決するために、こちら

mysqlコマンドラインツールなしで、mysqldump出力およびphpmyadminエクスポートを処理できます。 RailsのようなDBに保存されているタイムスタンプに基づいて、複数の移行ファイルを処理するロジックも作成しました。私はそれがより多くのエラー処理を必要とすることを知っていますが、現在私のために仕事をします。

チェックアウト: 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