74

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

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

4

30 に答える 30

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

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

$qr = $db->exec($sql);
于 2011-08-24T16:23:37.407 に答える
61

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 < $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 < $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 < $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("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $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 < $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("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $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';

// mysql_* is deprecated, prefer using mysqli_* instead
// mysql_connect($host,$user,$pass) or die('error connection');
// mysql_select_db($db) or die('error database selection');
$connection = mysqli_connect($host,$user,$pass) or die('error connection');
mysqli_select_db($connection, $db) or die('error database selection');

$i=1;
foreach($sql_query as $sql){
    echo $i++;
    echo "<br />";
    // mysql_* is deprecated, prefer using mysqli_* instead
    // mysql_query($sql) or die('error in query');
    mysqli_query($connection, $sql) or die('error in query');
}
于 2011-07-07T08:02:40.167 に答える
52

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

さて、OP に答えるために、最善の策は、変数にクエリを含む PHP ファイルを構築し、それらを実行できるようにすることです。.sql ファイルを解析することに決めた場合は、phpMyAdmin を調べて、その方法で .sql ファイルからデータを取得するためのアイデアを得る必要があります。インストーラーを備えた他の Web アプリケーションを見回すと、クエリに .sql ファイルを使用するのではなく、それらを PHP ファイルにパッケージ化し、mysql_query を介して各文字列を実行するだけであることがわかります。 .

于 2008-09-29T18:48:05.033 に答える
30

最も簡単な解決策は、shell_exec() を使用して、SQL スクリプトを入力として mysql クライアントを実行することです。これはフォークする必要があるため、実行が少し遅くなる可能性がありますが、数分でコードを記述してから、何か有用な作業に戻ることができます。SQL スクリプトを実行する PHP スクリプトを作成するには、数週間かかる場合があります。

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 スクリプトのサブセットのみをサポートする場合、ファイルを読み取り、ファイル内の SQL ステートメントを実行する PHP スクリプトを作成するのは比較的簡単です。ただし、有効な SQL スクリプトをサポートしたい場合は、はるかに複雑です。


これらの関連する質問に対する私の回答も参照してください。

于 2008-09-29T16:23:31.197 に答える
11

私のプロジェクトでは、次のソリューションを使用しました:

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

于 2013-03-12T06:04:19.873 に答える
10

mysqliで区切られた複数のクエリを実行できます;

ファイル全体を読み込んで、一度に実行することができますmysqli_multi_query()

しかし、これは最も洗練されたソリューションではないと最初に断言します。

于 2008-09-29T17:40:16.367 に答える
5

私の提案は、PHPMyBackup のソースコードを確認することです。自動化された PHP SQL ローダーです。mysql_query は一度に 1 つのクエリしかロードしないことがわかります。また、PHPMyAdmin や PHPMyBackup などのプロジェクトは、SQL を正しい方法で解析するという大変な作業を既に行っています。その車輪を再発明しないでください:P

于 2008-09-29T09:49:52.703 に答える
4

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 = '';
        }
    }
}
于 2012-07-17T14:54:40.110 に答える
4

簡単に言えば、私がこれを行った方法は次のとおりです。

  1. ファイルを読み取ります (db ダンプなど$ 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

于 2015-05-21T10:13:08.423 に答える
4
mysql_query("LOAD DATA LOCAL INFILE '/path/to/file' INTO TABLE mytable");
于 2008-09-29T07:48:19.703 に答える
3

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

いずれにせよ、オーレの方法が一番良さそうです。一度に 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);
}

明らかに、大量のクエリをバッチで実行している場合は、トランザクションなどを考慮する必要がありますが、新規インストール スクリプトの場合は、おそらく大した問題ではありません。

于 2008-09-29T08:21:16.553 に答える
3

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();
    }
}
于 2017-01-29T22:50:16.117 に答える
2

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 = "";
    }
  }
 }
于 2011-04-28T20:29:20.157 に答える
2

これを試して:

// 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);
于 2011-11-01T21:15:11.857 に答える
2

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

$ mysql -u username -p -h localhost dbname < dumpfile.sql 
于 2012-05-22T22:14:06.723 に答える
2

このThe Best Code for restore sql by phpは100%使用できます。どうもありがとうございます

$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 = "";
  }
 }
}
于 2011-10-24T17:55:11.020 に答える
2

巨大な.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の回答についてコメントしたように、を使用して分割することにより、壊れますクエリの文字列内にセミコロンがある場合)。

于 2008-09-29T08:41:08.813 に答える
1

None of the solutions I have seen here deal with needing to change the delimiter while creating a stored procedure on a server where I can't count on having access to LOAD DATA INFILE. I was hoping to find that someone had already solved this without having to scour the phpMyAdmin code to figure it out. Like others, I too was in the process of looking for someone else's GPL'ed way of doing it since I am writing GPL code myself.

于 2010-06-01T03:14:22.643 に答える
1

一部の PHP ライブラリは、複数の SQL ステートメントで構成された SQL ファイルを解析し、適切に展開し (単純な ";" 展開は当然使用しません)、それらを実行できます。

たとえば、PhingPDOSQLExecTaskを確認します。

于 2010-09-01T13:38:52.207 に答える
1

これは役に立つかもしれません -->

多かれ少なかれ、最初に関数に与えられた文字列 (file.sql の file_get_contents() 値) を取得し、すべての改行を削除します。次に、データを「;」で分割します。キャラクター。次に、作成された配列の各行を調べながら、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);
于 2013-10-23T15:18:14.433 に答える
1

みんなのために問題をもう一度言います:

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);
于 2011-09-10T20:10:49.863 に答える
1

多くのホストでは、PHP を使用して独自のデータベースを作成することはできませんが、それを解決したようです。
DB が作成されたら、簡単に操作および設定できます。

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

于 2011-10-30T09:01:41.420 に答える
1

一部の人 (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 = "";
            }
          }
         }

より包括的だからです。;-)

于 2013-09-19T11:08:05.847 に答える
0

次のコードが問題をうまく解決してくれることを願っています。

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

?>
于 2012-01-09T12:29:12.960 に答える
0

mysql ツールまたは phpmyadmin がなく、php アプリケーションが別のホスト上の mysql サーバーに接続している環境がありますが、mysqldump または myadmin によってエクスポートされたスクリプトを実行する必要があります。問題を解決するために、ここでmulti_query述べたようにスクリプトを作成しました

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

確認してください: https://github.com/kepes/php-migration

これは純粋な php であり、他のツールは必要ありません。開発者が作成したスクリプトやエクスポートツールのみでユーザー入力を処理しない場合は、安全に使用できます。

于 2015-01-21T09:26:24.437 に答える
0

私はいつもこれを使用しています:

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

foreach($sql as $query)
 mysql_query($query);
于 2011-01-12T15:43:13.640 に答える