灾备可视化:从数据中解读灾备 5月16日 星期四 15:00 云祺视频号准时直播
vinchin linked
delta 扫码预约直播,观看精彩内容!
closed
logo
关于我们

技术分享

技术分享 一个不错的MYSQL数据库备份类,PHP版,一个文件,精简版

一个不错的MYSQL数据库备份类,PHP版,一个文件,精简版

2021-06-02

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

 

云祺备份软件,云祺容灾备份系统,虚拟机备份,数据库备份,文件备份,实时备份,勒索软件,美国,图书馆
  • 标签:
  • 云计算

您可能感兴趣的新闻 换一批

现在下载,可享30天免费试用

立即下载