PHP 내에서 .sql 파일로드
개발중인 응용 프로그램에 대한 설치 스크립트를 만들고 있으며 PHP 내에서 동적으로 데이터베이스를 만들어야합니다. 데이터베이스를 만들 수 있지만 이제 여러 .sql 파일을로드해야합니다. 나는 파일을 열고 mysql_query를 한 번에 한 줄씩 열 계획을 세웠다. 스키마 파일을보고 그들이 한 줄에 하나의 쿼리가 아니라는 것을 깨달을 때까지.
그렇다면 phpMyAdmin이 가져 오기 명령으로 수행하는 것처럼 PHP 내에서 SQL 파일을 어떻게로드합니까?
이 질문에 답한 모든 사람들이 사람들이 자신의 서버에 응용 프로그램을 설치할 수있게하는 웹 응용 프로그램 개발자가되는 것이 어떤 것인지 모른다는 느낌을 받고 있습니다. 특히 공유 호스팅에서는 앞서 언급 한 "LOAD DATA"쿼리와 같은 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 < $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';
//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 스크립트에 나타날 수있는 몇 가지 예입니다.
-- 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 스크립트를 지원하려면 훨씬 더 복잡합니다.
다음 관련 질문에 대한 내 답변도 참조하십시오.
- PHP에서 MySQL * .sql 파일 실행
- 다른 SQL 스크립트의 저장 프로 시저에서 SQL 스크립트를 호출 할 수 있습니까?
- PHP : 하나의 mysql_query 문에서 여러 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에서 테스트 됨).
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 = '';
}
}
}
내 제안은 PHPMyBackup의 소스 코드를 보는 것입니다. 자동화 된 PHP SQL 로더입니다. mysql_query는 한 번에 하나의 쿼리 만로드하며 PHPMyAdmin 및 PHPMyBackup과 같은 프로젝트는 이미 SQL을 올바른 방식으로 구문 분석하는 데 많은 노력을 기울였습니다. 그 바퀴를 다시 발명하지 마십시오 : P
한 줄에 하나의 쿼리가 아닌 것이 확실합니까? 텍스트 편집기는 줄 바꿈 일 수 있지만 실제로는 각 쿼리가 한 줄에있을 수 있습니다.
어쨌든 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() > 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");
간단히 말해서 내가 한 방법은 다음과 같습니다.
파일 읽기 (예 : db 덤프
$ mysqldump db > db.sql)$sql = file_get_contents(db.sql);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
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();
}
}
대용량 .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의 답변에 대해 언급했듯이을 사용하여 분할 하면 중단됩니다. 쿼리의 문자열 내에 세미콜론이있는 경우) ..
이것은 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 = "";
}
}
}
phpmyadmin 덤프 또는 mysql 덤프 파일을로드하고 구문 분석하는 가장 쉽고 빠른 방법 ..
$ mysql -u username -p -h localhost dbname < dumpfile.sql
여기서 본 솔루션 중 어느 것도 LOAD DATA INFILE에 대한 액세스 권한을 가질 수없는 서버에서 저장 프로 시저를 만드는 동안 구분 기호를 변경해야하는 문제를 다루지 않습니다. 나는 누군가가 그것을 알아 내기 위해 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 ( "로컬 호스트");
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.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);
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에서 내 보낸 스크립트를 실행해야합니다. 문제를 해결하기 위해 여기서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;
}
?>
참고 URL : https://stackoverflow.com/questions/147821/loading-sql-files-from-within-php
'Nice programing' 카테고리의 다른 글
| html에서 UL 또는 OL을 언제 사용합니까? (0) | 2020.11.25 |
|---|---|
| PIP 설치에서 libffi를 인식하더라도 ffi.h를 찾을 수 없습니다. (0) | 2020.11.25 |
| Android에서 color 및 color.darker를 사용하십니까? (0) | 2020.11.25 |
| Entity Framework 코어 : DbContextOptionsBuilder '에'usesqlserver '에 대한 정의가 포함되어 있지 않고 확장 메서드'usesqlserver '가 없습니다. (0) | 2020.11.25 |
| 작업 표시 줄에 뒤로 버튼 추가 (0) | 2020.11.25 |