如何使用PHP在mysql数据库中导入.sql文件?


74

我正在尝试通过PHP代码导入.sql文件。但是,我的代码显示此错误:

There was an error during import. Please make sure the import file is saved in the same folder as this script and check your values:

MySQL Database Name:    test
MySQL User Name:    root
MySQL Password: NOTSHOWN
MySQL Host Name:    localhost
MySQL Import Filename:  dbbackupmember.sql

这是我的代码:

<?php
//ENTER THE RELEVANT INFO BELOW
$mysqlDatabaseName ='test';
$mysqlUserName ='root';
$mysqlPassword ='';
$mysqlHostName ='localhost';
$mysqlImportFilename ='dbbackupmember.sql';
//DONT EDIT BELOW THIS LINE
//Export the database and output the status to the page
$command='mysql -h' .$mysqlHostName .' -u' .$mysqlUserName .' -p' .$mysqlPassword .' ' .$mysqlDatabaseName .' < ' .$mysqlImportFilename;
exec($command,$output=array(),$worked);
switch($worked){
    case 0:
        echo 'Import file <b>' .$mysqlImportFilename .'</b> successfully imported to database <b>' .$mysqlDatabaseName .'</b>';
        break;
    case 1:
        echo 'There was an error during import. Please make sure the import file is saved in the same folder as this script and check your values:<br/><br/><table><tr><td>MySQL Database Name:</td><td><b>' .$mysqlDatabaseName .'</b></td></tr><tr><td>MySQL User Name:</td><td><b>' .$mysqlUserName .'</b></td></tr><tr><td>MySQL Password:</td><td><b>NOTSHOWN</b></td></tr><tr><td>MySQL Host Name:</td><td><b>' .$mysqlHostName .'</b></td></tr><tr><td>MySQL Import Filename:</td><td><b>' .$mysqlImportFilename .'</b></td></tr></table>';
        break;
}
?>

我究竟做错了什么?SQL文件位于同一目录中。


2
您确定dbbackupmember.sql文件与脚本位于同一目录中吗?什么var_dump( file_exists('dbbackupmember.sql') );输出?
阿马尔·穆拉利

是的,这是同一目录,但我不知道为什么它显示错误
msalman

Apache进程是否可以访问转储存储的文件夹/文件?是否exec('whoami')返回您的用户名?有时,由于权限的原因,exec在apache进程中也不起作用。
本诺


2
这回答了你的问题了吗?如何在MySQL中使用命令行导入SQL文件?
Dharman

Answers:


144

警告: mysql_*自PHP 5.5.0起,扩展名已弃用,自PHP 7.0.0起,扩展名已删除。相反,应使用mysqliPDO_MySQL扩展名。另请参见MySQL API概述,以获取选择MySQL API时的更多帮助。
只要有可能,应将文件导入MySQL委托给MySQL客户端。

我有另一种方法可以尝试

<?php

// Name of the file
$filename = 'churc.sql';
// MySQL host
$mysql_host = 'localhost';
// MySQL username
$mysql_username = 'root';
// MySQL password
$mysql_password = '';
// Database name
$mysql_database = 'dump';

// Connect to MySQL server
mysql_connect($mysql_host, $mysql_username, $mysql_password) or die('Error connecting to MySQL server: ' . mysql_error());
// Select database
mysql_select_db($mysql_database) or die('Error selecting MySQL database: ' . mysql_error());

// 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 = '';
}
}
 echo "Tables imported successfully";
?>

这对我有用


4
杜德!救了我!:D因为我有大量的转储文件,所以我需要流式传输文件而不是一次读取所有文件……请参阅此处http://stackoverflow.com/a/13246630/1050264
v01pe 2014年

1
我添加了这个:if(substr($ line,0,2)==“ / *”){continue;}。帮忙
不间断的

1
不要使用此功能,因为您很快就会耗尽内存!
Alex Skrypnyk '16

1
@Enrique您可以向我详细说明一下:D我应该先做什么,上传文件.sql,然后保留上面的继续脚本!我的问题是数据库更新或替换为新数据库
Freddy Sidauruk

@FreddySidauruk,您应该上传文件并将其放在脚本所在的文件夹中。然后执行脚本。数据库应该是空的,除非你确定.sql文件将在数据库中更新正确的一切,表,视图,等等
恩里克

36

警告: mysql_*自PHP 5.5.0起,扩展名已弃用,自PHP 7.0.0起,扩展名已删除。相反,应使用mysqliPDO_MySQL扩展名。另请参见MySQL API概述,以获取选择MySQL API时的更多帮助。
只要有可能,应将文件导入MySQL委托给MySQL客户端。

Raj的答案很有用,但是(由于file($ filename))如果您的mysql-dump不适合内存,它将失败

如果您在共享主机上,并且有30 MB和12s脚本运行时的限制,并且必须还原x00MB mysql dump,则可以使用以下脚本:

它将在转储文件查询中进行查询,如果脚本执行截止日期临近,它将当前文件位置保存在tmp文件中,并且自动重新加载浏览器将一次又一次地继续此过程...如果发生错误,则重新加载将停止并显示错误...

如果您从午餐回来,您的数据库将恢复;-)

noLimitDumpRestore.php:

// your config
$filename = 'yourGigaByteDump.sql';
$dbHost = 'localhost';
$dbUser = 'user';
$dbPass = '__pass__';
$dbName = 'dbname';
$maxRuntime = 8; // less then your max script execution limit


$deadline = time()+$maxRuntime; 
$progressFilename = $filename.'_filepointer'; // tmp file for progress
$errorFilename = $filename.'_error'; // tmp file for erro

mysql_connect($dbHost, $dbUser, $dbPass) OR die('connecting to host: '.$dbHost.' failed: '.mysql_error());
mysql_select_db($dbName) OR die('select db: '.$dbName.' failed: '.mysql_error());

($fp = fopen($filename, 'r')) OR die('failed to open file:'.$filename);

// check for previous error
if( file_exists($errorFilename) ){
    die('<pre> previous error: '.file_get_contents($errorFilename));
}

// activate automatic reload in browser
echo '<html><head> <meta http-equiv="refresh" content="'.($maxRuntime+2).'"><pre>';

// go to previous file position
$filePosition = 0;
if( file_exists($progressFilename) ){
    $filePosition = file_get_contents($progressFilename);
    fseek($fp, $filePosition);
}

$queryCount = 0;
$query = '';
while( $deadline>time() AND ($line=fgets($fp, 1024000)) ){
    if(substr($line,0,2)=='--' OR trim($line)=='' ){
        continue;
    }

    $query .= $line;
    if( substr(trim($query),-1)==';' ){
        if( !mysql_query($query) ){
            $error = 'Error performing query \'<strong>' . $query . '\': ' . mysql_error();
            file_put_contents($errorFilename, $error."\n");
            exit;
        }
        $query = '';
        file_put_contents($progressFilename, ftell($fp)); // save the current file position for 
        $queryCount++;
    }
}

if( feof($fp) ){
    echo 'dump successfully restored!';
}else{
    echo ftell($fp).'/'.filesize($filename).' '.(round(ftell($fp)/filesize($filename), 2)*100).'%'."\n";
    echo $queryCount.' queries processed! please reload or wait for automatic browser refresh!';
}

您的脚本也解决了我的问题!我有2.4GB的大型SQL,无法控制允许的文件大小和查询大小的增加。万分感谢!
Sinisa

这可以通过更新mysqli来完成。mysql_connect在php 5.5中已弃用,并在7中删除
Chris Mccabe

使用此脚本,我遇到了一些特殊字符(ö,ä,²,³..)的问题,但不是每个表中都有。通过上面的ManojGeek脚本,它可以正常工作。
哈里

1
@ user2355808 -那奇怪-因为展位脚本使用相同的功能,并没有字符集无关的函数(文件和MySQL查询与fgets和mysql的查询),也许你的DB-创作是不同的
粮食

请注意客户端缓存。另外,可以将刷新时间设置为1,因为在加载页面之前计时器不会运行。
Sanquira Van Delbar

32

您可以使用mysqli multi_query函数,如下所示:

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

$mysqli = new mysqli("localhost", "root", "pass", "testdb");

/* execute multi query */
$mysqli->multi_query($sql);

4
这比接受的答案快很多。准确地说要快100倍。(我测量了)。
雪球

1
如果由于某种原因您不能使用命令行mysql命令,那么这是首选。使用multi_query时要小心,因为它是异步的,之后必须运行阻塞循环。
Dharman

1
要补充Dharman所说的内容,需要注意的是,您需要能够将整个转储文件读入内存才能使之正常工作,因此它仅适用于较小的文件。如果您有一个1GB的转储文件,则由于内存不足,该操作将失败。大型转储文件只能通过MySQL命令行进行处理
Machavity

8
<?php
$host = "localhost";
$uname = "root";
$pass = "";
$database = "demo1"; //Change Your Database Name
$conn = new mysqli($host, $uname, $pass, $database);
$filename = 'users.sql'; //How to Create SQL File Step : url:http://localhost/phpmyadmin->detabase select->table select->Export(In Upper Toolbar)->Go:DOWNLOAD .SQL FILE
$op_data = '';
$lines = file($filename);
foreach ($lines as $line)
{
    if (substr($line, 0, 2) == '--' || $line == '')//This IF Remove Comment Inside SQL FILE
    {
        continue;
    }
    $op_data .= $line;
    if (substr(trim($line), -1, 1) == ';')//Breack Line Upto ';' NEW QUERY
    {
        $conn->query($op_data);
        $op_data = '';
    }
}
echo "Table Created Inside " . $database . " Database.......";
?>

6
<?php
system('mysql --user=USER --password=PASSWORD DATABASE< FOLDER/.sql');
?>

2
这是推荐的解决方案。将文件导入MySQL时应始终委托给MySQL客户端。
Dharman

3

我已经测试了您的代码,当您已经导入数据库或使用某些具有相同名称的表时,将显示此错误,同时显示的Array错误是因为您在exec括号中添加了,这是固定版本:

<?php
//ENTER THE RELEVANT INFO BELOW
$mysqlDatabaseName ='test';
$mysqlUserName ='root';
$mysqlPassword ='';
$mysqlHostName ='localhost';
$mysqlImportFilename ='dbbackupmember.sql';
//DONT EDIT BELOW THIS LINE
//Export the database and output the status to the page
$command='mysql -h' .$mysqlHostName .' -u' .$mysqlUserName .' -p' .$mysqlPassword .' ' .$mysqlDatabaseName .' < ' .$mysqlImportFilename;
$output=array();
exec($command,$output,$worked);
switch($worked){
    case 0:
        echo 'Import file <b>' .$mysqlImportFilename .'</b> successfully imported to database <b>' .$mysqlDatabaseName .'</b>';
        break;
    case 1:
        echo 'There was an error during import.';
        break;
}
?> 

这是推荐的解决方案。将文件导入MySQL时应始终委托给MySQL客户端。
Dharman

2

Grain Script非常棒,可以拯救我的生活。同时,mysql已贬值,我使用PDO重写了Grain答案。

    $server  =  'localhost'; 
    $username   = 'root'; 
    $password   = 'your password';  
    $database = 'sample_db';

    /* PDO connection start */
    $conn = new PDO("mysql:host=$server; dbname=$database", $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);         
    $conn->exec("SET CHARACTER SET utf8");     
    /* PDO connection end */

    // your config
    $filename = 'yourFile.sql';

    $maxRuntime = 8; // less then your max script execution limit


    $deadline = time()+$maxRuntime; 
    $progressFilename = $filename.'_filepointer'; // tmp file for progress
    $errorFilename = $filename.'_error'; // tmp file for erro



    ($fp = fopen($filename, 'r')) OR die('failed to open file:'.$filename);

    // check for previous error
    if( file_exists($errorFilename) ){
        die('<pre> previous error: '.file_get_contents($errorFilename));
    }

    // activate automatic reload in browser
    echo '<html><head> <meta http-equiv="refresh" content="'.($maxRuntime+2).'"><pre>';

    // go to previous file position
    $filePosition = 0;
    if( file_exists($progressFilename) ){
        $filePosition = file_get_contents($progressFilename);
        fseek($fp, $filePosition);
    }

    $queryCount = 0;
    $query = '';
    while( $deadline>time() AND ($line=fgets($fp, 1024000)) ){
        if(substr($line,0,2)=='--' OR trim($line)=='' ){
            continue;
        }

        $query .= $line;
        if( substr(trim($query),-1)==';' ){

            $igweze_prep= $conn->prepare($query);

            if(!($igweze_prep->execute())){ 
                $error = 'Error performing query \'<strong>' . $query . '\': ' . print_r($conn->errorInfo());
                file_put_contents($errorFilename, $error."\n");
                exit;
            }
            $query = '';
            file_put_contents($progressFilename, ftell($fp)); // save the current file position for 
            $queryCount++;
        }
    }

    if( feof($fp) ){
        echo 'dump successfully restored!';
    }else{
        echo ftell($fp).'/'.filesize($filename).' '.(round(ftell($fp)/filesize($filename), 2)*100).'%'."\n";
        echo $queryCount.' queries processed! please reload or wait for automatic browser refresh!';
    }

我认为您和Grain完成后需要取消Filepointer文件的链接,不是吗?否则,如果您重新上传相同的文件名,它将仅继续尝试从该最终指针运行
Dss19,19年

1
// Import data 
$filename = 'database_file_name.sql';
import_tables('localhost','root','','database_name',$filename);

function import_tables($host,$uname,$pass,$database, $filename,$tables = '*'){
    $connection = mysqli_connect($host,$uname,$pass)
    or die("Database Connection Failed");
    $selectdb = mysqli_select_db($connection, $database) or die("Database could not be selected"); 

$templine = '';
$lines = file($filename); // Read entire file

foreach ($lines as $line){
    // Skip it if it's a comment
    if (substr($line, 0, 2) == '--' || $line == '' || substr($line, 0, 2) == '/*' )
        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) == ';')
        {
            mysqli_query($connection, $templine)
            or print('Error performing query \'<strong>' . $templine . '\': ' . mysqli_error($connection) . '<br /><br />');
            $templine = '';
        }
    }
    echo "Tables imported successfully";
}




// Backup database from php script
backup_tables('hostname','UserName','pass','databses_name');

function backup_tables($host,$user,$pass,$name,$tables = '*'){
    $link = mysqli_connect($host,$user,$pass);
    if (mysqli_connect_errno()){
        echo "Failed to connect to MySQL: " . mysqli_connect_error();
    }

    mysqli_select_db($link,$name);
    //get all of the tables
    if($tables == '*'){
        $tables = array();
        $result = mysqli_query($link,'SHOW TABLES');
        while($row = mysqli_fetch_row($result))
        {
            $tables[] = $row[0];
        }
    }else{
        $tables = is_array($tables) ? $tables : explode(',',$tables);
    }

    $return = '';
    foreach($tables as $table)
    {
        $result = mysqli_query($link,'SELECT * FROM '.$table);
        $num_fields = mysqli_num_fields($result);
        $row_query = mysqli_query($link,'SHOW CREATE TABLE '.$table);
        $row2 = mysqli_fetch_row($row_query);
        $return.= "\n\n".$row2[1].";\n\n";

        for ($i = 0; $i < $num_fields; $i++) 
        {
            while($row = mysqli_fetch_row($result))
            {
                $return.= 'INSERT INTO '.$table.' VALUES(';
                for($j=0; $j < $num_fields; $j++) 
                {
                    $row[$j] = addslashes($row[$j]);
                    $row[$j] = str_replace("\n", '\n', $row[$j]);
                    if (isset($row[$j])) { 
                        $return.= '"'.$row[$j].'"' ; 
                    } else { 
                        $return.= '""'; 
                    }
                    if ($j < ($num_fields-1)) { $return.= ','; }
                }
                $return.= ");\n";
            }
        }
        $return.="\n\n\n";
    }

    //save file
    $handle = fopen('backup-'.date("d_m_Y__h_i_s_A").'-'.(md5(implode(',',$tables))).'.sql','w+');
    fwrite($handle,$return);
    fclose($handle);
}

是否更改了脚本的功能及其工作方式的解释?
汤姆(Tom)”

1

如果您需要用户界面并且要使用PDO

这是一个简单的解决方案

<form method="post" enctype="multipart/form-data">
    <input type="text" name="db" placeholder="Databasename" />
    <input type="file" name="file">
    <input type="submit" name="submit" value="submit">
</form>

<?php

if(isset($_POST['submit'])){
    $query = file_get_contents($_FILES["file"]["name"]);
    $dbname = $_POST['db'];
    $con = new PDO("mysql:host=localhost;dbname=$dbname","root","");
    $stmt = $con->prepare($query);
    if($stmt->execute()){
        echo "Successfully imported to the $dbname.";
    }
}
?>

绝对是我的目标。值得一试。


0

如果您使用的是PHP 7或更高版本,请尝试以下脚本,

// Name of the file
$filename = 'sql.sql';
// MySQL host
$mysql_host = 'localhost';
// MySQL username
$mysql_username = 'username';
// MySQL password
$mysql_password = 'password';
// Database name
$mysql_database = 'database';
// Connect to MySQL server
$con = @new mysqli($mysql_host,$mysql_username,$mysql_password,$mysql_database);
// Check connection
if ($con->connect_errno) {
   echo "Failed to connect to MySQL: " . $con->connect_errno;
   echo "<br/>Error: " . $con->connect_error;
}
// 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
$con->query($templine) or print('Error performing query \'<strong>' . $templine . '\': ' . $con->error() . '<br /><br />');
    // Reset temp variable to empty
    $templine = '';
}
}
echo "Tables imported successfully";
$con->close($con);

-1

我使用此代码,然后运行RUN SUCCESS FULL:

$filename = 'apptoko-2016-12-23.sql'; //change to ur .sql file
                            $handle = fopen($filename, "r+");
                            $contents = fread($handle, filesize($filename));

                            $sql = explode(";",$contents);// 
                            foreach($sql as $query){
                                $result=mysql_query($query);
                                if ($result){
                                 echo '<tr><td><BR></td></tr>';
                                 echo '<tr><td>' . $query . ' <b>SUCCESS</b></td></tr>';
                                 echo '<tr><td><BR></td></tr>';
                                }
                            }
                            fclose($handle);

-1

解决特殊字符

 $link=mysql_connect($dbHost, $dbUser, $dbPass) OR die('connecting to host: '.$dbHost.' failed: '.mysql_error());
mysql_select_db($dbName) OR die('select db: '.$dbName.' failed: '.mysql_error());

//charset important
mysql_set_charset('utf8',$link);

-1

我可以尝试使用此代码,它已针对我的情况运行:

<?php

$con = mysqli_connect('localhost', 'root', 'NOTSHOWN', 'test');

$filename = 'dbbackupmember.sql';
$handle = fopen($filename, 'r+');
$contents = fread($handle, filesize($filename));

$sql = explode(";", $contents);
foreach ($sql as $query) {
	$result = mysqli_query($con, $query);
	if ($result) {
		echo "<tr><td><br></td></tr>";
		echo "<tr><td>".$query."</td></tr>";
		echo "<tr><td><br></td></tr>";
	}
}

fclose($handle);
echo "success";


?>


-1
function restoreDatabase($db_name,$file_path)
{

    //checking valid extension file
    $path_parts = pathinfo($file_path);
    $ext_file = $path_parts['extension'];
    $filename = $path_parts['basename'];

    if($ext_file == "sql")
    {
         $c = new Config();

         $confJson = $c->getConfig();
         $conf = json_decode($confJson);

         $dbhost   = "127.0.0.1";
         $dbuser   = $conf->db_username;  
         $dbpwd    = $conf->db_password;
         $dbname   = $db_name;   

         $dumpfile = $file_path;

         $is_file = file_exists($file_path);
         if($is_file == TRUE)
         {

             //passthru("/usr/bin/mysqldump --opt --host=$dbhost --user=$dbuser --password=$dbpwd $dbname < $dumpfile");

             //passthru("tail -1 $dumpfile");
             system('mysql --user='.$dbuser.' --password='.$dbpwd.' '.$db_name.' < '.$file_path);
             return "Database was restored from $filename ";

         }
         else 
         {
             return "Restore database was aborted due ".$filename." does not exist!";
         }


    }
    else
    {
        return "Invalid file format.Require sql file to restore this ".$db_name." database. ".$filename." is not sql file format\n(eg. mybackupfile.sql).";
    }
}

-1

众所周知,MySQL在PHP 5.5.0中已弃用,在PHP 7.0.0 ref中已将其删除,因此我已将接受的答案转换为mysqli。

<?php
// Name of the file
$filename = 'db.sql';
// MySQL host
$mysql_host = 'localhost';
// MySQL username
$mysql_username = 'root';
// MySQL password
$mysql_password = '123456';
// Database name
$mysql_database = 'mydb';

$connection = mysqli_connect($mysql_host,$mysql_username,$mysql_password,$mysql_database) or die(mysqli_error($connection));

// 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
    mysqli_query($connection,$templine) or print('Error performing query \'<strong>' . $templine . '\': ' . mysqli_error($connection) . '<br /><br />');
    // Reset temp variable to empty
    $templine = '';
}
}
 echo "Tables imported successfully";
?>

这是值得称赞的,但现实是这是一种可怕的做法。我不建议,我必须投票。使用MySQL备份功能,而不是或multi_query(小心)
Dharman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.