【问题标题】:Export MySQL database using PHP [closed]使用 PHP 导出 MySQL 数据库 [关闭]
【发布时间】:2014-04-07 09:03:42
【问题描述】:

我已经构建了一个 php/mysql (wamp) 应用程序并部署在本地工作站上。 我的客户想保存数据库并在他喜欢的时候恢复它。

我找到了保存代码:

<?php


$DB_HOST = "localhost";
$DB_USER = "root";
$DB_PASS = "admin";
$DB_NAME = "dbname";

$con = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);

 
 $tables = array();

$result = mysqli_query($con,"SHOW TABLES");
while ($row = mysqli_fetch_row($result)) {
    $tables[] = $row[0];
}

$return = '';

foreach ($tables as $table) {
    $result = mysqli_query($con, "SELECT * FROM ".$table);
    $num_fields = mysqli_num_fields($result);

    $return .= 'DROP TABLE '.$table.';';
    $row2 = mysqli_fetch_row(mysqli_query($con, 'SHOW CREATE TABLE '.$table));
    $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]);
                if (isset($row[$j])) {
                    $return .= '"'.$row[$j].'"';} else { $return .= '""';}
                    if($j<$num_fields-1){ $return .= ','; }
                }
                $return .= ");\n";
            }
        }
        $return .= "\n\n\n";
    
}


$handle = fopen('backup.sql', 'w+');
fwrite($handle, $return);
fclose($handle);

echo "success";

?>

此代码将文件保存在默认文件夹中。 我需要的是让用户决定在哪里保存备份文件,或者只是通过浏览器下载。 另一方面,用户需要从他想要的文件中恢复,所以我需要一个“浏览”按钮,让他在他的任何文件夹中选择文件。

我的数据库是 utf8_general_ci 并且有英语、法语和意大利语我不需要复杂的代码,因为我不知道如何管理它们:-(

提前致谢。

【问题讨论】:

标签: php mysql backup


【解决方案1】:

使用 php 脚本导出数据库的最佳方式。

或添加特定表的第 5 个参数(数组):array("mytable1","mytable2","mytable3") 用于多个表

<?php 
    //ENTER THE RELEVANT INFO BELOW
    $mysqlUserName      = "Your Username";
    $mysqlPassword      = "Your Password";
    $mysqlHostName      = "Your Host";
    $DbName             = "Your Database Name here";
    $backup_name        = "mybackup.sql";
    $tables             = "Your tables";

   //or add 5th parameter(array) of specific tables:    array("mytable1","mytable2","mytable3") for multiple tables

    Export_Database($mysqlHostName,$mysqlUserName,$mysqlPassword,$DbName,  $tables=false, $backup_name=false );

    function Export_Database($host,$user,$pass,$name,  $tables=false, $backup_name=false )
    {
        $mysqli = new mysqli($host,$user,$pass,$name); 
        $mysqli->select_db($name); 
        $mysqli->query("SET NAMES 'utf8'");

        $queryTables    = $mysqli->query('SHOW TABLES'); 
        while($row = $queryTables->fetch_row()) 
        { 
            $target_tables[] = $row[0]; 
        }   
        if($tables !== false) 
        { 
            $target_tables = array_intersect( $target_tables, $tables); 
        }
        foreach($target_tables as $table)
        {
            $result         =   $mysqli->query('SELECT * FROM '.$table);  
            $fields_amount  =   $result->field_count;  
            $rows_num=$mysqli->affected_rows;     
            $res            =   $mysqli->query('SHOW CREATE TABLE '.$table); 
            $TableMLine     =   $res->fetch_row();
            $content        = (!isset($content) ?  '' : $content) . "\n\n".$TableMLine[1].";\n\n";

            for ($i = 0, $st_counter = 0; $i < $fields_amount;   $i++, $st_counter=0) 
            {
                while($row = $result->fetch_row())  
                { //when started (and every after 100 command cycle):
                    if ($st_counter%100 == 0 || $st_counter == 0 )  
                    {
                            $content .= "\nINSERT INTO ".$table." VALUES";
                    }
                    $content .= "\n(";
                    for($j=0; $j<$fields_amount; $j++)  
                    { 
                        $row[$j] = str_replace("\n","\\n", addslashes($row[$j]) ); 
                        if (isset($row[$j]))
                        {
                            $content .= '"'.$row[$j].'"' ; 
                        }
                        else 
                        {   
                            $content .= '""';
                        }     
                        if ($j<($fields_amount-1))
                        {
                                $content.= ',';
                        }      
                    }
                    $content .=")";
                    //every after 100 command cycle [or at last line] ....p.s. but should be inserted 1 cycle eariler
                    if ( (($st_counter+1)%100==0 && $st_counter!=0) || $st_counter+1==$rows_num) 
                    {   
                        $content .= ";";
                    } 
                    else 
                    {
                        $content .= ",";
                    } 
                    $st_counter=$st_counter+1;
                }
            } $content .="\n\n\n";
        }
        //$backup_name = $backup_name ? $backup_name : $name."___(".date('H-i-s')."_".date('d-m-Y').")__rand".rand(1,11111111).".sql";
        $backup_name = $backup_name ? $backup_name : $name.".sql";
        header('Content-Type: application/octet-stream');   
        header("Content-Transfer-Encoding: Binary"); 
        header("Content-disposition: attachment; filename=\"".$backup_name."\"");  
        echo $content; exit;
    }
?>

【讨论】:

  • 在主机不允许 shell exec 时很有用,谢谢。
  • 您还必须添加`反引号,以防有名称使用如match或set(它们是mysql中的关键字)
  • @alessadro 如果你只有一个表,然后在 $tables = 'your_table_name' 上添加你的表名,如果你想添加多个表,然后在 $tables 上传递数组,如 $tables = array('tbl_1 ','tbl_2','tbl_3');在第 8 行。无需定义任何其他参数。
  • 这是如何工作的?
  • @RajuDudhrejiya,我不是在问这个,我已经使用了你的解决方案。我在问技术点这是如何工作的。什么是逻辑。我查看代码还是有很多困惑。
【解决方案2】:

这个工具可能很有用,它是一个纯粹的基于 PHP 的导出实用程序:https://github.com/2createStudio/shuttle-export

【讨论】:

  • 即使在服务器上禁用了 shell 命令,这个解决方案也能很好地工作,我将在我未来的项目中使用这个类,非常感谢你的分享!
  • 这个工具很棒,但请记住不支持utf-8等特殊字符集。
【解决方案3】:

试试下面的。

从 PHP 文件执行数据库备份查询。以下是使用 SELECT INTO OUTFILE 查询创建表备份的示例:

<?php
$DB_HOST = "localhost";
$DB_USER = "xxx";
$DB_PASS = "xxx";
$DB_NAME = "xxx";

$con = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);
if($con->connect_errno > 0) {
  die('Connection failed [' . $con->connect_error . ']');
}

$tableName  = 'yourtable';
$backupFile = 'backup/yourtable.sql';
$query      = "SELECT * INTO OUTFILE '$backupFile' FROM $tableName";
$result = mysqli_query($con,$query);
?>

要恢复备份,您只需像这样运行 LOAD DATA INFILE 查询:

<?php
$DB_HOST = "localhost";
$DB_USER = "xxx";
$DB_PASS = "xxx";
$DB_NAME = "xxx";

$con = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);
if($con->connect_errno > 0) {
  die('Connection failed [' . $con->connect_error . ']');
}

$tableName  = 'yourtable';
$backupFile = 'yourtable.sql';
$query      = "LOAD DATA INFILE 'backupFile' INTO TABLE $tableName";
$result = mysqli_query($con,$query);
?>

【讨论】:

  • 弗雷德很好的答案。关于备份的一个问题。我可以看到我需要手动输入表名有什么办法可以自动化。我有 200 多张桌子。请指教。
  • @CalculatingMachine 你需要某种类型的foreach 循环。这是一个很好的问题,你应该考虑提出一个问题。但是请先搜索一下,可能已经有一些东西了。如果你愿意,我很乐意投票;让我知道您是否以及何时发布问题。
  • 感谢您的评论弗雷德。实际上我搜索了很多并找到了一些答案,但这些答案不完整。我很早就认识你了,我知道你的回答是准确的。投票赞成。并且会牢记搜索和提出好问题。再次感谢。
  • 非常欢迎您@CalculatingMachine,谢谢,干杯
  • 谨慎使用此方法,因为它需要您具有 FILE 权限才能运行它。 Bitnami Wordpress 是托管设置的示例,默认情况下未启用。
【解决方案4】:

在 *nix 系统中,使用 WHICH 命令显示 mysqldump 的位置,试试这个:

<?php
$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = 'password';
$dbname = 'test';
$mysqldump=exec('which mysqldump');


$command = "$mysqldump --opt -h $dbhost -u $dbuser -p $dbpass $dbname > $dbname.sql";

exec($command);
?>

【讨论】:

  • 我没有 shell 访问权限。
  • @Daan 你必须有 shell 访问权限或 PHPMyAdmin...没有这两个你会怎么做
  • 你会为远程服务器做什么
  • 您可以在顶部添加流动代码: //设置编码 mysql_query("SET CHARSET utf8"); mysql_query("SET NAMES 'utf8' COLLATE 'utf8_general_ci'");
  • 为了使它与我的数据库凭据一起工作,我修改了这一行: $command = "$mysqldump --opt -h\"$dbhost\" -u\"$dbuser\" -p\" $dbpass\" $dbname > $tempFile";
【解决方案5】:
<?php
 $dbhost = 'localhost:3036';
 $dbuser = 'root';
 $dbpass = 'rootpassword';

 $conn = mysql_connect($dbhost, $dbuser, $dbpass);

 if(! $conn ) {
  die('Could not connect: ' . mysql_error());
 }

 $table_name = "employee";
 $backup_file  = "/tmp/employee.sql";
 $sql = "SELECT * INTO OUTFILE '$backup_file' FROM $table_name";

 mysql_select_db('test_db');
 $retval = mysql_query( $sql, $conn );

 if(! $retval ) {
  die('Could not take data backup: ' . mysql_error());
 }

 echo "Backedup  data successfully\n";

 mysql_close($conn);
?>

【讨论】:

    【解决方案6】:

    这是我的代码,这将备份 MySQL 数据库并将其存储在指定路径中。

    <?php
    function backup_mysql_database($options){
    $mtables = array(); $contents = "-- Database: `".$options['db_to_backup']."` --\n";
    
    $mysqli = new mysqli($options['db_host'], $options['db_uname'], $options['db_password'], $options['db_to_backup']);
    if ($mysqli->connect_error) {
        die('Error : ('. $mysqli->connect_errno .') '. $mysqli->connect_error);
    }
    
    $results = $mysqli->query("SHOW TABLES");
    
    while($row = $results->fetch_array()){
        if (!in_array($row[0], $options['db_exclude_tables'])){
            $mtables[] = $row[0];
        }
    }
    
    foreach($mtables as $table){
        $contents .= "-- Table `".$table."` --\n";
    
        $results = $mysqli->query("SHOW CREATE TABLE ".$table);
        while($row = $results->fetch_array()){
            $contents .= $row[1].";\n\n";
        }
    
        $results = $mysqli->query("SELECT * FROM ".$table);
        $row_count = $results->num_rows;
        $fields = $results->fetch_fields();
        $fields_count = count($fields);
    
        $insert_head = "INSERT INTO `".$table."` (";
        for($i=0; $i < $fields_count; $i++){
            $insert_head  .= "`".$fields[$i]->name."`";
                if($i < $fields_count-1){
                        $insert_head  .= ', ';
                    }
        }
        $insert_head .=  ")";
        $insert_head .= " VALUES\n";        
    
        if($row_count>0){
            $r = 0;
            while($row = $results->fetch_array()){
                if(($r % 400)  == 0){
                    $contents .= $insert_head;
                }
                $contents .= "(";
                for($i=0; $i < $fields_count; $i++){
                    $row_content =  str_replace("\n","\\n",$mysqli->real_escape_string($row[$i]));
    
                    switch($fields[$i]->type){
                        case 8: case 3:
                            $contents .=  $row_content;
                            break;
                        default:
                            $contents .= "'". $row_content ."'";
                    }
                    if($i < $fields_count-1){
                            $contents  .= ', ';
                        }
                }
                if(($r+1) == $row_count || ($r % 400) == 399){
                    $contents .= ");\n\n";
                }else{
                    $contents .= "),\n";
                }
                $r++;
            }
        }
    }
    
    if (!is_dir ( $options['db_backup_path'] )) {
            mkdir ( $options['db_backup_path'], 0777, true );
     }
    
    $backup_file_name = $options['db_to_backup'] . " sql-backup- " . date( "d-m-Y--h-i-s").".sql";
    
    $fp = fopen($options['db_backup_path'] . '/' . $backup_file_name ,'w+');
    if (($result = fwrite($fp, $contents))) {
        echo "Backup file created '--$backup_file_name' ($result)"; 
    }
    fclose($fp);
    return $backup_file_name;
    }
    
    $options = array(
        'db_host'=> 'localhost',  //mysql host
        'db_uname' => 'root',  //user
        'db_password' => '', //pass
        'db_to_backup' => 'attendance', //database name
        'db_backup_path' => '/htdocs', //where to backup
        'db_exclude_tables' => array() //tables to exclude
    );
    $backup_file_name=backup_mysql_database($options);
    

    【讨论】:

      【解决方案7】:

      如果你没有phpMyAdmin,你可以在php CLI 中编写login to mysql 等命令并执行db dump。在这种情况下,您将使用shell_exec 函数。

      【讨论】:

      • 我提到我没有 shell 访问权限,但我有 phpMyAdmin。客户想在他的网站上备份他的数据库。
      • 你不需要。只需在 php 文件中运行它,看看它是否有效。 &lt;?php shell_exec("mkdir test"); ?&gt; 然后检查 php 文件所在的根文件夹并查找 test 文件夹。与您可以使用终端 sintax 登录 mysql 并将 db 提取到特定文件夹的方式相同。我之前做过,我测试过的系统是Win7。
      【解决方案8】:

      我建议您执行以下操作,

      <?php
      
      $con = mysqli_connect('HostName', 'UserName', 'Password', 'DatabaseName');
      
      
      $tables = array();
      
      $result = mysqli_query($con,"SHOW TABLES");
      while ($row = mysqli_fetch_row($result)) {
      	$tables[] = $row[0];
      }
      
      $return = '';
      
      foreach ($tables as $table) {
      	$result = mysqli_query($con, "SELECT * FROM ".$table);
      	$num_fields = mysqli_num_fields($result);
      
      	$return .= 'DROP TABLE '.$table.';';
      	$row2 = mysqli_fetch_row(mysqli_query($con, 'SHOW CREATE TABLE '.$table));
      	$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]);
      				if (isset($row[$j])) {
      					$return .= '"'.$row[$j].'"';} else { $return .= '""';}
      					if($j<$num_fields-1){ $return .= ','; }
      				}
      				$return .= ");\n";
      			}
      		}
      		$return .= "\n\n\n";
      	
      }
      
      
      $handle = fopen('backup.sql', 'w+');
      fwrite($handle, $return);
      fclose($handle);
      echo "success";
      
      
      ?>

      更新。修复了代码中的错误,在 $return .= 'INSERT INTO '.$table.'VALUES(';

      行中的 VALUES 之前添加了空格

      【讨论】:

      • 你为什么要删除所有表???
      【解决方案9】:

      我建议您执行以下操作,

      <?php
      
      function EXPORT_TABLES($host, $user, $pass, $name, $tables = false, $backup_name = false)
      {
          $mysqli      = new mysqli($host, $user, $pass, $name);
          $mysqli->select_db($name);
          $mysqli->query("SET NAMES 'utf8'");
          $queryTables = $mysqli->query('SHOW TABLES');
          while ($row         = $queryTables->fetch_row())
          {
              $target_tables[] = $row[0];
          }
          if ($tables !== false)
          {
              $target_tables = array_intersect($target_tables, $tables);
          }
          $content = "SET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\";\r\nSET time_zone = \"+00:00\";\r\n\r\n\r\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;\r\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;\r\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;\r\n/*!40101 SET NAMES utf8 */;\r\n--Database: `" . $name . "`\r\n\r\n\r\n";
          foreach ($target_tables as $table)
          {
              $result        = $mysqli->query('SELECT * FROM ' . $table);
              $fields_amount = $result->field_count;
              $rows_num      = $mysqli->affected_rows;
              $res           = $mysqli->query('SHOW CREATE TABLE ' . $table);
              $TableMLine    = $res->fetch_row();
              $content .= "\n\n" . $TableMLine[1] . ";\n\n";
              for ($i = 0, $st_counter = 0; $i < $fields_amount; $i++, $st_counter = 0)
              {
                  while ($row = $result->fetch_row())
                  { //when started (and every after 100 command cycle):
                      if ($st_counter % 100 == 0 || $st_counter == 0)
                      {
                          $content .= "\nINSERT INTO " . $table . " VALUES";
                      }
                      $content .= "\n(";
                      for ($j = 0; $j < $fields_amount; $j++)
                      {
                          $row[$j] = str_replace("\n", "\\n", addslashes($row[$j]));
                          if (isset($row[$j]))
                          {
                              $content .= '"' . $row[$j] . '"';
                          }
                          else
                          {
                              $content .= '""';
                          } if ($j < ($fields_amount - 1))
                          {
                              $content.= ',';
                          }
                      }
                      $content .=")";
                      //every after 100 command cycle [or at last line] ....p.s. but should be inserted 1 cycle eariler
                      if ((($st_counter + 1) % 100 == 0 && $st_counter != 0) || $st_counter + 1 == $rows_num)
                      {
                          $content .= ";";
                      }
                      else
                      {
                          $content .= ",";
                      } $st_counter = $st_counter + 1;
                  }
              } $content .="\n\n\n";
          }
          $content .= "\r\n\r\n/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\r\n/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\r\n/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;";
          $backup_name = $backup_name ? $backup_name : $name . "___(" . date('H-i-s') . "_" . date('d-m-Y') . ")__rand" . rand(1, 11111111) . ".sql";
          header('Content-Type: application/octet-stream');
          header("Content-Transfer-Encoding: Binary");
          header("Content-disposition: attachment; filename=\"" . $backup_name . "\"");
          echo $content;
          exit;
      }
      ?>
      

      可以在https://github.com/tazotodua/useful-php-scripts找到整个导出和导入项目。

      【讨论】:

        【解决方案10】:

        你可以使用这个命令它工作或我 100%

        exec('C:\\wamp\\bin\\mysql\\mysql5.6.17\\bin\\mysqldump.exe -uroot DatabaseName> c:\\database_backup.sql');
        

        注意:
        C:\\wamp\\bin\\mysql\\mysql5.6.17\\bin\\mysqldump.exe 是 mysqldump 应用的路径,请在你的电脑上查看。

        -uroot-u{UserName}

        如果您的数据库受密码保护,则在 -uroot 后添加此句 -p{YourPassword}

        【讨论】:

          猜你喜欢
          • 2015-09-09
          • 2013-02-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多