php 数据库导入导出类

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:
Java代码   收藏代码
  1. <?php  
  2. /** 
  3.  * 创建时间: 2012年5月21日 
  4.  * 
  5.  * 说明:分卷文件是以_v1.sql为结尾(20120522021241_all_v1.sql) 
  6.  * 功能:实现mysql数据库分卷备份,选择表进行备份,实现单个sql文件及分卷sql导入 
  7.  * 使用方法: 
  8.  * 
  9.  * ------1. 数据库备份(导出)------------------------------------------------------------ 
  10. //分别是主机,用户名,密码,数据库名,数据库编码 
  11. $db = new DBManage ( 'localhost', 'root', 'root', 'test', 'utf8' ); 
  12. // 参数:备份哪个表(可选),备份目录(可选,默认为backup),分卷大小(可选,默认2000,即2M) 
  13. $db->backup (); 
  14.  * ------2. 数据库恢复(导入)------------------------------------------------------------ 
  15. //分别是主机,用户名,密码,数据库名,数据库编码 
  16. $db = new DBManage ( 'localhost', 'root', 'root', 'test', 'utf8' ); 
  17. //参数:sql文件 
  18. $db->restore ( './backup/20120516211738_all_v1.sql'); 
  19.  *---------------------------------------------------------------------- 
  20.  */  
  21. class DBManage  
  22. {  
  23.     var $db; // 数据库连接  
  24.     var $database; // 所用数据库  
  25.     var $sqldir; // 数据库备份文件夹  
  26.     var $record;  
  27.     // 换行符  
  28.     private $ds = "\n";  
  29.     // 存储SQL的变量  
  30.     public $sqlContent = "";  
  31.     // 每条sql语句的结尾符  
  32.     public $sqlEnd = ";";  
  33.     /** 
  34.      * 初始化 
  35.      * 
  36.      * @param string $host 
  37.      * @param string $username 
  38.      * @param string $password 
  39.      * @param string $thisatabase 
  40.      * @param string $charset 
  41.      */  
  42.     function __construct($host = 'localhost', $username = 'root', $password = '', $thisatabase = 'test', $charset = 'utf8')  
  43.     {  
  44.         $this->host = $host;  
  45.         $this->username = $username;  
  46.         $this->password = $password;  
  47.         $this->database = $thisatabase;  
  48.         $this->charset = $charset;  
  49.         // 连接数据库  
  50.         $this->db = mysql_connect ( $this->host, $this->username, $this->password ) or die ( "数据库连接失败." );  
  51.         // 选择使用哪个数据库  
  52.         mysql_select_db ( $this->database, $this->db ) or die ( "无法打开数据库" );  
  53.         // 数据库编码方式  
  54.         mysql_query ( 'SET NAMES ' . $this->charset, $this->db );  
  55.     }  
  56.   
  57.     /* 
  58.       * ------------------------------------------数据库备份start---------------------------------------------------------- 
  59.       */  
  60.   
  61.     /** 
  62.      * 数据库备份 
  63.      * 参数:备份哪个表(可选),备份目录(可选,默认为backup),分卷大小(可选,默认2000,即2M) 
  64.      * 
  65.      * @param $string $dir 
  66.      * @param int $size 
  67.      * @param $string $tablename 
  68.      */  
  69.     function backup($tablename = '', $dir, $size)  
  70.     {  
  71.         $dir = $dir ? $dir : 'backup/';  
  72.         $size = $size ? $size : 2000;  
  73.         $sql = '';  
  74.         // 只备份某个表  
  75.         if (! empty ( $tablename ))  
  76.         {  
  77.             echo '正在备份表' . $tablename . '<br />';  
  78.             // 插入dump信息  
  79.             $sql = $this->_retrieve();  
  80.             // 插入表结构信息  
  81.             $sql .= $this->_insert_table_structure ( $tablename );  
  82.             // 插入数据  
  83.             $data = mysql_query ( "select * from " . $tablename );  
  84.             // 文件名前面部分  
  85.             $filename = date ( 'YmdHis' ) . "_" . $tablename;  
  86.             // 字段数量  
  87.             $num_fields = mysql_num_fields ( $data );  
  88.             // 第几分卷  
  89.             $p = 1;  
  90.             // 循环每条记录  
  91.             while ( $record = mysql_fetch_array ( $data ) )  
  92.             {  
  93.                 // 单条记录  
  94.                 $sql .= $this->_insert_record ( $tablename, $num_fields, $record );  
  95.                 // 如果大于分卷大小,则写入文件  
  96.                 if (strlen ( $sql ) >= $size * 1000)  
  97.                 {  
  98.                     $file = $filename . "_v" . $p . ".sql";  
  99.                     if ($this->_write_file ( $sql, $file, $dir ))  
  100.                     {  
  101.                         echo "表-" . $tablename . "-卷-" . $p . "-数据备份完成,生成备份文件 <span style='color:#f00;'>$dir$filename</span><br />";  
  102.                     }  
  103.                     else  
  104.                     {  
  105.                         echo "备份表-" . $tablename . "-失败<br />";  
  106.                     }  
  107.                     // 下一个分卷  
  108.                     $p ++;  
  109.                     // 重置$sql变量为空,重新计算该变量大小  
  110.                     $sql = "";  
  111.                 }  
  112.             }  
  113.             // sql大小不够分卷大小  
  114.             if ($sql != "")  
  115.             {  
  116.                 $filename .= "_v" . $p . ".sql";  
  117.                 if ($this->_write_file ( $sql, $filename, $dir ))  
  118.                 {  
  119.                     echo "表-" . $tablename . "-卷-" . $p . "-数据备份完成,生成备份文件 <span style='color:#f00;'>$dir$filename</span><br />";  
  120.                 }  
  121.                 else  
  122.                 {  
  123.                     echo "备份卷-" . $p . "-失败<br />";  
  124.                 }  
  125.             }  
  126.         }  
  127.         else  
  128.         { // 备份全部表  
  129.             if ($tables = mysql_query ( "show table status from " . $this->database ))  
  130.             {  
  131.                 echo "读取数据库结构成功!<br />";  
  132.             }  
  133.             else  
  134.             {  
  135.                 exit ( "读取数据库结构成功!<br />" );  
  136.             }  
  137.             // 插入dump信息  
  138.             $sql .= $this->_retrieve();  
  139.             // 文件名前面部分  
  140.             $filename = date ( 'YmdHis' ) . "_all";  
  141.             // 查出所有表  
  142.             $tables = mysql_query ( 'SHOW TABLES' );  
  143.             // 第几分卷  
  144.             $p = 1;  
  145.             // 循环所有表  
  146.             while ( $table = mysql_fetch_array ( $tables ) )  
  147.             {  
  148.                 // 获取表名  
  149.                 $tablename = $table [0];  
  150.                 // 获取表结构  
  151.                 $sql .= $this->_insert_table_structure ( $tablename );  
  152.                 $data = mysql_query ( "select * from " . $tablename );  
  153.                 $num_fields = mysql_num_fields ( $data );  
  154.   
  155.                 // 循环每条记录  
  156.                 while ( $record = mysql_fetch_array ( $data ) )  
  157.                 {  
  158.                     // 单条记录  
  159.                     $sql .= $this->_insert_record ( $tablename, $num_fields, $record );  
  160.                     // 如果大于分卷大小,则写入文件  
  161.                     if (strlen ( $sql ) >= $size * 1000)  
  162.                     {  
  163.   
  164.                         $file = $filename . "_v" . $p . ".sql";  
  165.                         // 写入文件  
  166.                         if ($this->_write_file ( $sql, $file, $dir ))  
  167.                         {  
  168.                             echo "-卷-" . $p . "-数据备份完成,生成备份文件<span style='color:#f00;'>$dir$file</span><br />";  
  169.                         }  
  170.                         else  
  171.                         {  
  172.                             echo "备份卷-" . $p . "-失败<br />";  
  173.                         }  
  174.                         // 下一个分卷  
  175.                         $p ++;  
  176.                         // 重置$sql变量为空,重新计算该变量大小  
  177.                         $sql = "";  
  178.                     }  
  179.                 }  
  180.             }  
  181.             // sql大小不够分卷大小  
  182.             if ($sql != "")  
  183.             {  
  184.                 $filename .= "_v" . $p . ".sql";  
  185.                 if ($this->_write_file ( $sql, $filename, $dir ))  
  186.                 {  
  187.                     echo "-卷-" . $p . "-数据备份完成,生成备份文件 <span style='color:#f00;'>$dir$filename<br />";  
  188.                 }  
  189.                 else  
  190.                 {  
  191.                     echo "备份卷-" . $p . "-失败<br />";  
  192.                 }  
  193.             }  
  194.         }  
  195.     }  
  196.   
  197.     /** 
  198.      * 插入数据库备份基础信息 
  199.      * 
  200.      * @return string 
  201.      */  
  202.     private function _retrieve() {  
  203.         $value = '';  
  204.         $value .= '--' . $this->ds;  
  205.         $value .= '-- MySQL database dump' . $this->ds;  
  206.         $value .= '-- Created by DBManage class, Power By yanue. ' . $this->ds;  
  207.         $value .= '-- http://yanue.net ' . $this->ds;  
  208.         $value .= '--' . $this->ds;  
  209.         $value .= '-- 主机: ' . $this->host . $this->ds;  
  210.         $value .= '-- 生成日期: ' . date ( 'Y' ) . ' 年  ' . date ( 'm' ) . ' 月 ' . date ( 'd' ) . ' 日 ' . date ( 'H:i' ) . $this->ds;  
  211.         $value .= '-- MySQL版本: ' . mysql_get_server_info () . $this->ds;  
  212.         $value .= '-- PHP 版本: ' . phpversion () . $this->ds;  
  213.         $value .= $this->ds;  
  214.         $value .= '--' . $this->ds;  
  215.         $value .= '-- 数据库: `' . $this->database . '`' . $this->ds;  
  216.         $value .= '--' . $this->ds . $this->ds;  
  217.         $value .= '-- -------------------------------------------------------';  
  218.         $value .= $this->ds . $this->ds;  
  219.         return $value;  
  220.     }  
  221.   
  222.     /** 
  223.      * 插入表结构 
  224.      * 
  225.      * @param unknown_type $table 
  226.      * @return string 
  227.      */  
  228.     private function _insert_table_structure($table) {  
  229.         $sql = '';  
  230.         $sql .= "--" . $this->ds;  
  231.         $sql .= "-- 表的结构" . $table . $this->ds;  
  232.         $sql .= "--" . $this->ds . $this->ds;  
  233.   
  234.         // 如果存在则删除表  
  235.         $sql .= "DROP TABLE IF EXISTS `" . $table . '`' . $this->sqlEnd . $this->ds;  
  236.         // 获取详细表信息  
  237.         $res = mysql_query ( 'SHOW CREATE TABLE `' . $table . '`' );  
  238.         $row = mysql_fetch_array ( $res );  
  239.         $sql .= $row [1];  
  240.         $sql .= $this->sqlEnd . $this->ds;  
  241.         // 加上  
  242.         $sql .= $this->ds;  
  243.         $sql .= "--" . $this->ds;  
  244.         $sql .= "-- 转存表中的数据 " . $table . $this->ds;  
  245.         $sql .= "--" . $this->ds;  
  246.         $sql .= $this->ds;  
  247.         return $sql;  
  248.     }  
  249.   
  250.     /** 
  251.      * 插入单条记录 
  252.      * 
  253.      * @param string $table 
  254.      * @param int $num_fields 
  255.      * @param array $record 
  256.      * @return string 
  257.      */  
  258.     private function _insert_record($table, $num_fields, $record) {  
  259.         // sql字段逗号分割  
  260.         $insert = $comma = "";  
  261.         $insert .= "INSERT INTO `" . $table . "` VALUES(";  
  262.         // 循环每个子段下面的内容  
  263.         for($i = 0; $i < $num_fields; $i ++) {  
  264.             $insert .= ($comma . "'" .mysql_real_escape_string ( $record [$i] ) . "'");  
  265.             $comma = ",";  
  266.         }  
  267.         $insert .= ");" . $this->ds;  
  268.         return $insert;  
  269.     }  
  270.   
  271.     /** 
  272.      * 写入文件 
  273.      * 
  274.      * @param string $sql 
  275.      * @param string $filename 
  276.      * @param string $dir 
  277.      * @return boolean 
  278.      */  
  279.     private function _write_file($sql, $filename, $dir) {  
  280.         $dir = $dir ? $dir : './backup/';  
  281.         // 不存在文件夹则创建  
  282.         if (! file_exists ( $dir )) {  
  283.             mkdir ( $dir );  
  284.         }  
  285.         $re = true;  
  286.         if (! @$fp = fopen ( $dir . $filename, "w+" )) {  
  287.             $re = false;  
  288.             echo "打开文件失败!";  
  289.         }  
  290.         if (! @fwrite ( $fp, $sql )) {  
  291.             $re = false;  
  292.             echo "写入文件失败,请文件是否可写";  
  293.         }  
  294.         if (! @fclose ( $fp )) {  
  295.             $re = false;  
  296.             echo "关闭文件失败!";  
  297.         }  
  298.         return $re;  
  299.     }  
  300.   
  301.     /* 
  302.       * 
  303.       * -------------------------------上:数据库导出-----------分割线----------下:数据库导入-------------------------------- 
  304.       */  
  305.   
  306.     /** 
  307.      * 导入备份数据 
  308.      * 说明:分卷文件格式20120516211738_all_v1.sql 
  309.      * 参数:文件路径(必填) 
  310.      * 
  311.      * @param string $sqlfile 
  312.      */  
  313.     function restore($sqlfile)  
  314.     {  
  315.         // 检测文件是否存在  
  316.         if (! file_exists ( $sqlfile ))  
  317.         {  
  318.             exit ( "文件不存在!请检查" );  
  319.         }  
  320.         $this->lock ( $this->database );  
  321.         // 获取数据库存储位置  
  322.         $sqlpath = pathinfo ( $sqlfile );  
  323.         $this->sqldir = $sqlpath ['dirname'];  
  324.         // 检测是否包含分卷,将类似20120516211738_all_v1.sql从_v分开,有则说明有分卷  
  325.         $volume = explode ( "_v", $sqlfile );  
  326.         $volume_path = $volume [0];  
  327.         echo "请勿刷新及关闭浏览器以防止程序被中止,如有不慎!将导致数据库结构受损<br />";  
  328.         echo "正在导入备份数据,请稍等!<br />";  
  329.         if (empty ( $volume [1] ))  
  330.         {  
  331.             echo "正在导入sql:<span style='color:#f00;'>" . $sqlfile . '</span><br />';  
  332.             // 没有分卷  
  333.             if ($this->_import ( $sqlfile )) {  
  334.                 echo "数据库导入成功!";  
  335.             }  
  336.             else  
  337.             {  
  338.                 exit ( '数据库导入失败!' );  
  339.             }  
  340.         }  
  341.         else  
  342.         {  
  343.             //$volume_id = array();  
  344.             // 存在分卷,则获取当前是第几分卷,循环执行余下分卷  
  345.             $volume_id = explode ( ".sq", $volume [1] );  
  346.             // 当前分卷为$volume_id  
  347.             $volume_id = intval ( $volume_id [0] );  
  348.             while ( $volume_id )  
  349.             {  
  350.                 $tmpfile = $volume_path . "_v" . $volume_id . ".sql";  
  351.                 // 存在其他分卷,继续执行  
  352.                 if (file_exists ( $tmpfile )) {  
  353.                     // 执行导入方法  
  354.                     echo "正在导入分卷$volume_id:<span style='color:#f00;'>" . $tmpfile . '</span><br />';  
  355.                     if ($this->_import ( $tmpfile ))  
  356.                     {  
  357.   
  358.                     }  
  359.                     else  
  360.                     {  
  361.                         exit ( "导入分卷$volume_id:<span style='color:#f00;'>" . $tmpfile . '</span>失败!可能是数据库结构已损坏!请尝试从分卷1开始导入' );  
  362.                     }  
  363.                 }  
  364.                 else  
  365.                 {  
  366.                     echo "此分卷备份全部导入成功!<br />";  
  367.                     return;  
  368.                 }  
  369.                 $volume_id++;  
  370.             }  
  371.         }  
  372.     }  
  373.   
  374.     /** 
  375.      * 将sql导入到数据库(普通导入) 
  376.      * 
  377.      * @param string $sqlfile 
  378.      * @return boolean 
  379.      */  
  380.     private function _import($sqlfile) {  
  381.         // sql文件包含的sql语句数组  
  382.         $sqls = array ();  
  383.         $f = fopen ( $sqlfile, "rb" );  
  384.         // 创建表缓冲变量  
  385.         $create = '';  
  386.         while ( ! feof ( $f ) ) {  
  387.             // 读取每一行sql  
  388.             $line = fgets ( $f );  
  389.             // 如果包含'-- '等注释,或为空白行,则跳过  
  390.             if (trim ( $line ) == '' || preg_match ( '/--*?/', $line, $match )) {  
  391.                 continue;  
  392.             }  
  393.             // 如果结尾包含';'(即为一个完整的sql语句,这里是插入语句),并且不包含'ENGINE='(即创建表的最后一句),  
  394.             if (! preg_match ( '/;/', $line, $match ) || preg_match ( '/ENGINE=/', $line, $match )) {  
  395.                 // 将本次sql语句与创建表sql连接存起来  
  396.                 $create .= $line;  
  397.                 // 如果包含了创建表的最后一句  
  398.                 if (preg_match ( '/ENGINE=/', $create, $match )) {  
  399.                     // 则将其合并到sql数组  
  400.                     $sqls [] = $create;  
  401.                     // 清空当前,准备下一个表的创建  
  402.                     $create = '';  
  403.                 }  
  404.                 // 跳过本次  
  405.                 continue;  
  406.             }  
  407.             $sqls [] = $line;  
  408.         }  
  409.         fclose ( $f );  
  410.         // 循环sql语句数组,分别执行  
  411.         foreach ( $sqls as $sql ) {  
  412.             str_replace ( "\n""", $sql );  
  413.             if (! mysql_query ( trim ( $sql ) )) {  
  414.                 echo mysql_error ();  
  415.                 return false;  
  416.             }  
  417.         }  
  418.         return true;  
  419.     }  
  420.   
  421.     /* 
  422.       * -------------------------------数据库导入end--------------------------------- 
  423.       */  
  424.   
  425.     // 关闭数据库连接  
  426.     private function close() {  
  427.         mysql_close ( $this->db );  
  428.     }  
  429.   
  430.     // 锁定数据库,以免备份或导入时出错  
  431.     private function lock($tablename, $op = "WRITE") {  
  432.         if (mysql_query ( "lock tables " . $tablename . " " . $op ))  
  433.             return true;  
  434.         else  
  435.             return false;  
  436.     }  
  437.   
  438.     // 解锁  
  439.     private function unlock() {  
  440.         if (mysql_query ( "unlock tables" ))  
  441.             return true;  
  442.         else  
  443.             return false;  
  444.     }  
  445.   
  446.     // 析构  
  447.     function __destruct() {  
  448.         mysql_query ( "unlock tables", $this->db );  
  449.         mysql_close ( $this->db );  
  450.     }  
  451. }  

 

相关文章
|
29天前
|
SQL 缓存 PHP
PHP技术探究:优化数据库查询效率的实用方法
本文将深入探讨PHP中优化数据库查询效率的实用方法,包括索引优化、SQL语句优化以及缓存机制的应用。通过合理的优化策略和技巧,可以显著提升系统性能,提高用户体验,是PHP开发者不容忽视的重要议题。
|
1月前
|
Java 程序员 PHP
PHP对象和类
PHP对象和类
19 0
|
3月前
|
关系型数据库 MySQL PHP
|
1月前
|
JavaScript Java 关系型数据库
基于vue的MOBA类游戏攻略分享平台23(程序+数据库+论文)可帮忙远程调试
基于vue的MOBA类游戏攻略分享平台23(程序+数据库+论文)可帮忙远程调试
|
1月前
|
存储 PHP Apache
使用CFimagehost源码搭建无需数据库支持的PHP免费图片托管私人图床
使用CFimagehost源码搭建无需数据库支持的PHP免费图片托管私人图床
|
2月前
|
缓存 NoSQL PHP
百度搜索:蓝易云【如何使用PHP进行数据库索引优化?】
通过以上方法,你可以使用PHP进行数据库索引优化,提高数据库查询性能和整体应用性能。同时,定期维护数据库和优化查询语句也是保持数据库高性能的关键。
42 11
|
2月前
|
监控 关系型数据库 MySQL
PHP与MySQL的结合:实现局域网上网行为监控软件的数据库管理
在当今信息化时代,网络安全日益成为重要的话题。为了有效监控和管理局域网上网行为,开发一个基于PHP和MySQL的数据库管理系统是一个理想的选择。本文将介绍如何结合PHP和MySQL,开发一款简单而高效的局域网上网行为监控软件,并重点关注数据库管理方面的实现。
184 0
|
4月前
|
SQL 数据库连接 数据库
VB.NET 中使用SqlConnection类连接到Microsoft SQL Server数据库的详细步骤
VB.NET 中使用SqlConnection类连接到Microsoft SQL Server数据库的详细步骤
90 0
|
4月前
|
PHP 数据库
【PHP学习】—PHP连接数据库实现表单页面的验证功能(七)
【PHP学习】—PHP连接数据库实现表单页面的验证功能(七)