문제

저는 개발 중이고 PHP 내에서 동적으로 데이터베이스를 생성해야 하는 응용 프로그램에 대한 설치 스크립트를 만들고 있습니다.데이터베이스를 생성해야 하는데 이제 여러 .sql 파일을 로드해야 합니다.나는 파일을 열고 mysql_query를 한 번에 한 줄씩 열 계획이었습니다. 스키마 파일을 보고 그것이 한 줄에 하나의 쿼리가 아니라는 것을 깨달을 때까지 말입니다.

그렇다면 PHP 내에서 SQL 파일을 어떻게 로드합니까(phpMyAdmin이 import 명령을 사용하여 수행하는 것처럼)?

도움이 되었습니까?

해결책

이 질문에 응답 한 모든 사람들이 사람들이 자신의 서버에 응용 프로그램을 설치할 수있는 웹 애플리케이션 개발자가 무엇인지 모르는 느낌을 받고 있습니다. 특히 공유 호스팅은 앞에서 언급 한 "로드 데이터"쿼리와 같이 SQL을 사용할 수 없습니다. 대부분의 공유 호스트는 또한 shell_exec을 사용할 수 없습니다.

이제 OP에 답하기 위해 최선의 방법은 변수에 쿼리를 포함하는 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 ()를 사용하여 SQL 스크립트를 입력으로 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 스크립트의 서브 세트 만 지원하는 경우 파일을 읽고 파일 내에서 SQL 문을 실행하는 PHP 스크립트를 작성하는 것이 비교적 쉽습니다. 그러나 유효한 SQL 스크립트를 지원하려면 훨씬 더 복잡합니다.


다음과 관련된 질문에 대한 답변도 참조하십시오.

mysqli a로 분리 된 여러 쿼리를 실행할 수 있습니다 ;

전체 파일을 읽고 한 번에 모두 실행할 수 있습니다. 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');

오류가 발생하거나 거짓을 반환하지 않습니다 (PHP 5.5.14에서 테스트).

내 제안은 phpmybackup의 Sourcecode를 보는 것입니다. 자동화 된 PHP SQL 로더입니다. MySQL_Query는 한 번에 하나의 쿼리 만로드하고 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 = '';
        }
    }
}

라인 당 하나의 쿼리가 아니라고 확신합니까? 텍스트 편집기는 줄을 랩핑 할 수 있지만 실제로는 각 쿼리가 한 줄에있을 수 있습니다.

어쨌든 Olle의 방법은 가장 잘 보입니다. 시간에 쿼리를 실행 해야하는 이유가 있으면 파일에서 한 줄씩 파일을 읽을 수 있고 각 쿼리 끝에 세미콜론을 사용하여 삭제하십시오. 서버의 메모리에 훨씬 더 친절하기 때문에 거대한 문자열을 분할하려고하는 것보다 파일로 라인별로 읽는 것이 훨씬 좋습니다. 예시:

$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 > 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가 Async Queries를 지원합니다. 여기에 추가 : 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()

파일이 거대하지 않는 한 (예 : 여러 메가 바이트 이상), 한 번에 IT 라인을 실행하거나 여러 쿼리로 분할 할 이유가 없습니다 ( ;, CAM8001의 답변에 댓글을 달았을 때 쿼리에 shtrings 내에 반 콜론이 있으면 끊어집니다) ..

PHP에 의해 복원 SQL을위한 가장 좋은 코드는 100% gooooood를 사용할 수 있습니다! 많은 감사합니다

$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 

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

여기서 본 솔루션 중 어느 것도 구분자를 변경할 필요가 없으며 서버에서 저장된 프로 시저를 작성하여 데이터를로드 할 수없는 것으로 의심 할 수 없습니다. 나는 누군가가 phpmyadmin 코드를 닦지 않고 이미 이것을 해결하기를 바랐다. 다른 사람들과 마찬가지로, 나도 GPL 코드를 직접 작성하고 있기 때문에 다른 사람의 GPL이 그 일을하는 과정에있었습니다.

일부 PHP 라이브러리는 여러 SQL 문으로 만든 SQL 파일을 구문 분석하고 올바르게 폭발 할 수 있습니다 (간단한 사용하지 않음 ";"자연스럽게, 자연스럽게).

예를 들어, 확인하십시오 phing'에스 pdosqlexectask

모든 사람에게 문제를 해결하기 위해 :

PHP의 MySQL_Query는 각 SQL 명령을 자동으로 종료하며 추가로 매뉴얼에서 그렇게하는 것에 대해 매우 모호합니다. 하나의 명령을 넘어선 모든 것이 오류를 일으킬 것입니다.

다른 하나는 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 ( "localhost");
mysql_query ( "소스 파일 .sql");

일부 사람들 (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 = "";
            }
          }
         }

더 포괄적이기 때문입니다. ;-)

도움이 될 수 있습니다 ->

그 내용은 먼저 주어진 문자열을 함수 (파일의 file_get_contents () 값 .sql 값)에 가져 와서 모든 줄 브레이크를 제거하는 것입니다. 그런 다음 ";"에 의해 데이터를 분할합니다. 캐릭터. 다음으로 생성 된 배열의 각 라인을 보면서 while 루프로 들어갑니다. 라인에 "`"문자가 포함 된 경우, 주어진 라인 데이터에 대한 쿼리 및 Exection을 실행한다는 것을 알게됩니다.

암호:

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 내가 말했듯이 여기

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