《PHP實例:php實現(xiàn)mysql備份恢復(fù)分卷處理的方法》要點:
本文介紹了PHP實例:php實現(xiàn)mysql備份恢復(fù)分卷處理的方法,希望對您有用。如果有疑問,可以聯(lián)系我們。
PHP教程本文實例講述了php實現(xiàn)mysql備份恢復(fù)分卷處理的方法.分享給大家供大家參考.具體分析如下:
PHP教程分卷處理就是把握們要處理的數(shù)據(jù)分成一個個小文件進(jìn)行處理了,這里我來給大家介紹一個php mysql備份恢復(fù)分卷處理類,實現(xiàn)mysql數(shù)據(jù)庫分卷備份,選擇表進(jìn)行備份,實現(xiàn)單個sql文件及分卷sql導(dǎo)入.
PHP教程分卷導(dǎo)入類及思路詳解
PHP教程數(shù)據(jù)庫導(dǎo)入導(dǎo)出是一個后臺必要擁有的功能,網(wǎng)上一搜,有很多關(guān)于數(shù)據(jù)庫導(dǎo)入導(dǎo)出的,但基本上一個大的系統(tǒng),包含了許多我們并不需要的,而且他們都是自己的后臺的形式,我并不喜歡的是拿人家的東西整合到自己的后臺,我需要的是自己東西,于是參照了很多,自己寫了一個關(guān)于分卷導(dǎo)入類,以方便調(diào)用,歡迎大家拍磚.
PHP教程這里針對分卷文件是以‘_v1.sql'為結(jié)尾,實現(xiàn)單個sql文件及分卷sql導(dǎo)入,分卷導(dǎo)入可選擇是否當(dāng)前分卷導(dǎo)入余下分卷,我們只需要直接調(diào)用類即可完成.
PHP教程分別是主機(jī),用戶名,暗碼,數(shù)據(jù)庫名,數(shù)據(jù)庫編碼
代碼如下:
$db = new DataManage ( 'localhost', 'root', 'root', 'test', 'utf8' );
PHP教程sql文件,是否只導(dǎo)入單個sql(即如果有其他分卷也不導(dǎo)入).
代碼如下:
$db->restore ( './backup/20120516211738_all_v1.sql', false );
對應(yīng)如何去列出備份的sql文件或選擇sql之類的,自己去實現(xiàn),那個不在這個范疇了,也很簡單的.
PHP教程還有目前只實現(xiàn)了數(shù)據(jù)庫導(dǎo)入,關(guān)于數(shù)據(jù)庫導(dǎo)出的,正在編寫功能,下面是完整的類代碼,具體思路及實現(xiàn)代碼里面都有說明,這里不在贅述,代碼如下:
代碼如下:
<?php
/**
?* @author yanue
?* 說明:分卷文件是以_v1.sql為結(jié)尾
?* 功能:實現(xiàn)單個sql文件及分卷sql導(dǎo)入,分卷導(dǎo)入可選擇是否當(dāng)前分卷導(dǎo)入余下分卷
?* 使用方法:
?*
?*
?* ------------------------------------------------------------------
//分別是主機(jī),用戶名,暗碼,數(shù)據(jù)庫名,數(shù)據(jù)庫編碼
$db = new DataManage ( 'localhost', 'root', 'root', 'test', 'utf8' );
//sql文件,是否只導(dǎo)入單個sql(即如果有其他分卷也不導(dǎo)入)
$db->restore ( './backup/20120516211738_all_v1.sql', false );
?*----------------------------------------------------------------------
?*/
class DataManage {
?var $db; // 數(shù)據(jù)庫連接
?var $database; // 所用數(shù)據(jù)庫
?var $sqldir; // 數(shù)據(jù)庫備份文件夾
?
?/**
? * 初始化
? *
? * @param string $host
? * @param string $username
? * @param string $password
? * @param string $database
? * @param string $charset
? */
?function __construct($host = 'localhost', $username = 'root', $password = '', $database = 'test', $charset = 'utf8') {
? $this->host = $host;
? $this->username = $username;
? $this->password = $password;
? $this->database = $database;
? $this->charset = $charset;
? // 連接數(shù)據(jù)庫
? $this->db = mysql_connect ( $this->host, $this->username, $this->password ) or die ( "數(shù)據(jù)庫連接失敗." );
? // 選擇使用哪個數(shù)據(jù)庫
? mysql_select_db ( $this->database, $this->db ) or die ( "無法打開數(shù)據(jù)庫" );
? // 數(shù)據(jù)庫編碼方式
? mysql_query ( 'SET NAMES ' . $this->charset, $this->db );
?}
?
?/**
? * 導(dǎo)入備份數(shù)據(jù)
? * 說明:分卷文件格式20120516211738_all_v1.sql
? *
? * @param string $sqlfile
? * @param bool $single
? */
?function restore($sqlfile, $single = FALSE) {
? // 檢測文件是否存在
? if (! file_exists ( $sqlfile )) {
?? exit ( "文件不存在!請檢查" );
? }
? $this->lock ( $this->database );
? // 獲取數(shù)據(jù)庫存儲位置
? $sqlpath = pathinfo ( $sqlfile );
? $this->sqldir = $sqlpath ['dirname'];
? // 檢測是否包含分卷,將類似20120516211738_all_v1.sql從_v分開,有則說明有分卷
? $volume = explode ( "_v", $sqlfile );
? $volume_path = $volume [0];
? echo "請勿刷新及關(guān)閉瀏覽器以防止程序被中止,如有不慎!將導(dǎo)致數(shù)據(jù)庫結(jié)構(gòu)受損<br />";
? echo "正在導(dǎo)入備份數(shù)據(jù),請稍等!<br />";
? if (emptyempty ( $volume [1] ) || $single) {
?? echo "正在導(dǎo)入sql:<span style='color:#f00;'>" . $sqlfile . '</span><br />';
?? // 沒有分卷
?? if ($this->_import ( $sqlfile )) {
??? echo "數(shù)據(jù)庫導(dǎo)入成功!";
?? } else {
??? exit ( '數(shù)據(jù)庫導(dǎo)入失敗!' );
?? }
? } else {
?? // 存在分卷,則獲取當(dāng)前是第幾分卷,循環(huán)執(zhí)行余下分卷
?? $volume_id = explode ( ".sq", $volume [1] );
?? // 當(dāng)前分卷為$volume_id
?? $volume_id = intval ( $volume_id [0] );
?? while ( $volume_id ) {
??? $tmpfile = $volume_path . "_v" . $volume_id . ".sql";
??? // 存在其他分卷,繼續(xù)執(zhí)行
??? if (file_exists ( $tmpfile )) {
???? // 執(zhí)行導(dǎo)入方法
???? echo "正在導(dǎo)入分卷$volume_id:<span style='color:#f00;'>" . $tmpfile . '</span><br />';
???? if ($this->_import ( $tmpfile )) {
?
???? } else {
????? exit ( "導(dǎo)入分卷$volume_id:<span style='color:#f00;'>" . $tmpfile . '</span>失敗!可能是數(shù)據(jù)庫結(jié)構(gòu)已損壞!請嘗試從分卷1開始導(dǎo)入' );
???? }
??? } else {
???? echo "此分卷備份全部導(dǎo)入成功!<br />";
???? return;
??? }
??? $volume_id ++;
?? }
? }
?}
?
?/**
? * 將sql導(dǎo)入到數(shù)據(jù)庫(普通導(dǎo)入)
? *
? * @param string $sqlfile
? * @return boolean
? */
?private function _import($sqlfile) {
? $name = basename ( $sqlfile );
? $sqls = file ( $sqlfile );
? foreach ( $sqls as $sql ) {
?? str_replace ( "r", "", $sql );
?? str_replace ( "n", "", $sql );
?? if (! mysql_query ( trim ( $sql ), $this->db ))
??? return false;
? }
? return true;
?}
?
?// 關(guān)閉數(shù)據(jù)庫連接
?private function close() {
? mysql_close ( $this->db );
?}
?
?// 鎖定數(shù)據(jù)庫,以免備份或?qū)霑r出錯
?private function lock($tablename, $op = "WRITE") {
? if (mysql_query ( "lock tables " . $tablename . " " . $op ))
?? return true;
? else
?? return false;
?}
?
?// 解鎖
?private function unlock() {
? if (mysql_query ( "unlock tables" ))
?? return true;
? else
?? return false;
?}
?
?// 析構(gòu)
?function __destruct() {
? mysql_query ( "unlock tables", $this->db );
? mysql_close ( $this->db );
?}
}
?>
mysql備份恢復(fù)分卷處理,調(diào)用簡單.
PHP教程分卷導(dǎo)入思路:
PHP教程按行讀取sql文件,將每一行當(dāng)作完整的sql語句存到數(shù)組再循環(huán)執(zhí)行插入數(shù)據(jù)庫就可以了,但是在創(chuàng)建表語句分了多行,這個需要單獨處理,就這個花了我好長時間的.感覺文章好長啊,主要是那個類文件給占用了.
PHP教程更新說明:
PHP教程1.去除sql導(dǎo)入的時候排除sql文件里面的注釋'C ‘ 從而解決sql中單雙引號不能導(dǎo)入
PHP教程2.單行讀取后的sql直接執(zhí)行,避免重新將sql語句組合到數(shù)組中再從數(shù)組中讀取導(dǎo)入sql,提高效率.
PHP教程下載地址: https://github.com/yanue/Dbmanage
PHP教程導(dǎo)出后的sql文件格式如下:
代碼如下:
--
-- MySQL database dump
-- Created by DBManage class, Power By yanue.?
--
-- 主機(jī): localhost
-- 生成日期: 2012 年? 10 月 06 日 22:32
-- MySQL版本: 5.1.50-community
-- PHP 版本: 5.3.9-ZS5.6.0
?
--
-- 數(shù)據(jù)庫: `test`
--
?
-- -------------------------------------------------------
?
--
-- 表的結(jié)構(gòu)aa
--
?
DROP TABLE IF EXISTS `aa`;
CREATE TABLE `aa` (
? `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
? `content` text NOT NULL,
? PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
?
--
-- 轉(zhuǎn)存表中的數(shù)據(jù) aa
--
?
INSERT INTO `aa` VALUES('1','<p id="test"><span class='hahh' style="line-height:;">我是測試數(shù)據(jù) 呵呵</span></p>');
下面是類代碼:
代碼如下:
<?php
/**
?* @author yanue
?* @copyright? Copyright (c) 2012 yanue.net
?* @version 1.1
?* 創(chuàng)建時間: 2012年5月21日
?
更新時間: 2012年10月6日
更新說明: 1.去除sql導(dǎo)入的時候排除sql文件里面的注釋'-- ' 從而解決sql中單雙引號不能導(dǎo)入
2.單行讀取后的sql直接執(zhí)行,避免重新將sql語句組合到數(shù)組中再從數(shù)組中讀取導(dǎo)入sql,提高效率
?
?* 說明:分卷文件是以_v1.sql為結(jié)尾(20120522021241_all_v1.sql)
?* 功能:實現(xiàn)mysql數(shù)據(jù)庫分卷備份,選擇表進(jìn)行備份,實現(xiàn)單個sql文件及分卷sql導(dǎo)入
?* 使用方法:
?*
?* ------1. 數(shù)據(jù)庫備份(導(dǎo)出)------------------------------------------------------------
//分別是主機(jī),用戶名,暗碼,數(shù)據(jù)庫名,數(shù)據(jù)庫編碼
$db = new DBManage ( 'localhost', 'root', 'root', 'test', 'utf8' );
// 參數(shù):備份哪個表(可選),備份目錄(可選,默認(rèn)為backup),分卷大小(可選,默認(rèn)2000,即2M)
$db->backup ();
?* ------2. 數(shù)據(jù)庫恢復(fù)(導(dǎo)入)------------------------------------------------------------
//分別是主機(jī),用戶名,暗碼,數(shù)據(jù)庫名,數(shù)據(jù)庫編碼
$db = new DBManage ( 'localhost', 'root', 'root', 'test', 'utf8' );
//參數(shù):sql文件
$db->restore ( './backup/20120516211738_all_v1.sql');
?*----------------------------------------------------------------------
?*/
class DbManage {
??? var $db; // 數(shù)據(jù)庫連接
??? var $database; // 所用數(shù)據(jù)庫
??? var $sqldir; // 數(shù)據(jù)庫備份文件夾
??? // 換行符
??? private $ds = "n";
??? // 存儲SQL的變量
??? public $sqlContent = "";
??? // 每條sql語句的結(jié)尾符
??? public $sqlEnd = ";";
?
??? /**
???? * 初始化
???? *
???? * @param string $host
???? * @param string $username
???? * @param string $password
???? * @param string $database
???? * @param string $charset
???? */
??? function __construct($host = 'localhost', $username = 'root', $password = '', $database = 'test', $charset = 'utf8') {
??????? $this->host = $host;
??????? $this->username = $username;
??????? $this->password = $password;
??????? $this->database = $database;
??????? $this->charset = $charset;
??????? set_time_limit(0);//無時間限制
@ob_end_flush();
??????? // 連接數(shù)據(jù)庫
??????? $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>');
??????? // 選擇使用哪個數(shù)據(jù)庫
??????? mysql_select_db ( $this->database, $this->db ) or die('<p class="dbDebug"><span class="err">Mysql Connect Error:</span>'.mysql_error().'</p>');
??????? // 數(shù)據(jù)庫編碼方式
??????? mysql_query ( 'SET NAMES ' . $this->charset, $this->db );
?
??? }
?
??? /*
???? * 新增查詢數(shù)據(jù)庫表
???? */
??? function getTables() {
??????? $res = mysql_query ( "SHOW TABLES" );
??????? $tables = array ();
??????? while ( $row = mysql_fetch_array ( $res ) ) {
??????????? $tables [] = $row [0];
??????? }
??????? return $tables;
??? }
?
??? /*
???? *
???? * ------------------------------------------數(shù)據(jù)庫備份start----------------------------------------------------------
???? */
?
??? /**
???? * 數(shù)據(jù)庫備份
???? * 參數(shù):備份哪個表(可選),備份目錄(可選,默認(rèn)為backup),分卷大小(可選,默認(rèn)2000,即2M)
???? *
???? * @param $string $dir
???? * @param int $size
???? * @param $string $tablename
???? */
??? function backup($tablename = '', $dir, $size) {
??????? $dir = $dir ? $dir : './backup/';
??????? // 創(chuàng)建目錄
??????? if (! is_dir ( $dir )) {
??????????? mkdir ( $dir, 0777, true ) or die ( '創(chuàng)建文件夾失敗' );
??????? }
??????? $size = $size ? $size : 2048;
??????? $sql = '';
??????? // 只備份某個表
??????? if (! emptyempty ( $tablename )) {
??????????? if(@mysql_num_rows(mysql_query("SHOW TABLES LIKE '".$tablename."'")) == 1) {
???????????? } else {
??????????????? $this->_showMsg('表-<b>' . $tablename .'</b>-不存在,請檢查!',true);
??????????????? die();
??????????? }
??????????? $this->_showMsg('正在備份表 <span class="imp">' . $tablename.'</span>');
??????????? // 插入dump信息
??????????? $sql = $this->_retrieve ();
??????????? // 插入表結(jié)構(gòu)信息
??????????? $sql .= $this->_insert_table_structure ( $tablename );
??????????? // 插入數(shù)據(jù)
??????????? $data = mysql_query ( "select * from " . $tablename );
??????????? // 文件名前面部分
??????????? $filename = date ( 'YmdHis' ) . "_" . $tablename;
??????????? // 字段數(shù)量
??????????? $num_fields = mysql_num_fields ( $data );
??????????? // 第幾分卷
??????????? $p = 1;
??????????? // 循環(huán)每條記錄
??????????? while ( $record = mysql_fetch_array ( $data ) ) {
??????????????? // 單條記錄
??????????????? $sql .= $this->_insert_record ( $tablename, $num_fields, $record );
??????????????? // 如果大于分卷大小,則寫入文件
??????????????? if (strlen ( $sql ) >= $size * 1024) {
??????????????????? $file = $filename . "_v" . $p . ".sql";
??????????????????? if ($this->_write_file ( $sql, $file, $dir )) {
??????????????????????? $this->_showMsg("表-<b>" . $tablename . "</b>-卷-<b>" . $p . "</b>-數(shù)據(jù)備份完成,備份文件 [ <span class='imp'>" .$dir . $file ."</span> ]");
??????????????????? } else {
??????????????????????? $this->_showMsg("備份表 -<b>" . $tablename . "</b>- 失敗",true);
??????????????????????? return false;
??????????????????? }
??????????????????? // 下一個分卷
??????????????????? $p ++;
??????????????????? // 重置$sql變量為空,重新計算該變量大小
??????????????????? $sql = "";
??????????????? }
??????????? }
??????????? // 及時清除數(shù)據(jù)
??????????? unset($data,$record);
??????????? // sql大小不夠分卷大小
??????????? if ($sql != "") {
??????????????? $filename .= "_v" . $p . ".sql";
??????????????? if ($this->_write_file ( $sql, $filename, $dir )) {
??????????????????? $this->_showMsg( "表-<b>" . $tablename . "</b>-卷-<b>" . $p . "</b>-數(shù)據(jù)備份完成,備份文件 [ <span class='imp'>" .$dir . $filename ."</span> ]");
??????????????? } else {
??????????????????? $this->_showMsg("備份卷-<b>" . $p . "</b>-失敗<br />");
??????????????????? return false;
??????????????? }
??????????? }
??????????? $this->_showMsg("恭喜您! <span class='imp'>備份成功</span>");
??????? } else {
??????????? $this->_showMsg('正在備份');
??????????? // 備份全部表
??????????? if ($tables = mysql_query ( "show table status from " . $this->database )) {
??????????????? $this->_showMsg("讀取數(shù)據(jù)庫結(jié)構(gòu)成功!");
??????????? } else {
??????????????? $this->_showMsg("讀取數(shù)據(jù)庫結(jié)構(gòu)失敗!");
??????????????? exit ( 0 );
??????????? }
??????????? // 插入dump信息
??????????? $sql .= $this->_retrieve ();
??????????? // 文件名前面部分
??????????? $filename = date ( 'YmdHis' ) . "_all";
??????????? // 查出所有表
??????????? $tables = mysql_query ( 'SHOW TABLES' );
??????????? // 第幾分卷
??????????? $p = 1;
??????????? // 循環(huán)所有表
??????????? while ( $table = mysql_fetch_array ( $tables ) ) {
??????????????? // 獲取表名
??????????????? $tablename = $table [0];
??????????????? // 獲取表結(jié)構(gòu)
??????????????? $sql .= $this->_insert_table_structure ( $tablename );
??????????????? $data = mysql_query ( "select * from " . $tablename );
??????????????? $num_fields = mysql_num_fields ( $data );
?
??????????????? // 循環(huán)每條記錄
??????????????? while ( $record = mysql_fetch_array ( $data ) ) {
??????????????????? // 單條記錄
??????????????????? $sql .= $this->_insert_record ( $tablename, $num_fields, $record );
??????????????????? // 如果大于分卷大小,則寫入文件
??????????????????? if (strlen ( $sql ) >= $size * 1000) {
?
??????????????????????? $file = $filename . "_v" . $p . ".sql";
??????????????????????? // 寫入文件
??????????????????????? if ($this->_write_file ( $sql, $file, $dir )) {
??????????????????????????? $this->_showMsg("-卷-<b>" . $p . "</b>-數(shù)據(jù)備份完成,備份文件 [ <span class='imp'>".$dir.$file."</span> ]");
??????????????????????? } else {
??????????????????????????? $this->_showMsg("卷-<b>" . $p . "</b>-備份失敗!",true);
??????????????????????????? return false;
??????????????????????? }
??????????????????????? // 下一個分卷
??????????????????????? $p ++;
??????????????????????? // 重置$sql變量為空,重新計算該變量大小
??????????????????????? $sql = "";
??????????????????? }
??????????????? }
??????????? }
??????????? // sql大小不夠分卷大小
??????????? if ($sql != "") {
??????????????? $filename .= "_v" . $p . ".sql";
??????????????? if ($this->_write_file ( $sql, $filename, $dir )) {
??????????????????? $this->_showMsg("-卷-<b>" . $p . "</b>-數(shù)據(jù)備份完成,備份文件 [ <span class='imp'>".$dir.$filename."</span> ]");
??????????????? } else {
??????????????????? $this->_showMsg("卷-<b>" . $p . "</b>-備份失敗",true);
??????????????????? return false;
??????????????? }
??????????? }
??????????? $this->_showMsg("恭喜您! <span class='imp'>備份成功</span>");
??????? }
??? }
?
??? //? 及時輸出信息
??? private function _showMsg($msg,$err=false){
??????? $err = $err ? "<span class='err'>ERROR:</span>" : '' ;
??????? echo "<p class='dbDebug'>".$err . $msg."</p>";
??????? flush();
?
??? }
?
??? /**
???? * 插入數(shù)據(jù)庫備份基礎(chǔ)信息
???? *
???? * @return string
???? */
??? private function _retrieve() {
??????? $value = '';
??????? $value .= '--' . $this->ds;
??????? $value .= '-- MySQL database dump' . $this->ds;
??????? $value .= '-- Created by DbManage class, Power By yanue. ' . $this->ds;
??????? $value .= '-- http://yanue.net ' . $this->ds;
??????? $value .= '--' . $this->ds;
??????? $value .= '-- 主機(jī): ' . $this->host . $this->ds;
??????? $value .= '-- 生成日期: ' . date ( 'Y' ) . ' 年? ' . date ( 'm' ) . ' 月 ' . date ( 'd' ) . ' 日 ' . date ( 'H:i' ) . $this->ds;
??????? $value .= '-- MySQL版本: ' . mysql_get_server_info () . $this->ds;
??????? $value .= '-- PHP 版本: ' . phpversion () . $this->ds;
??????? $value .= $this->ds;
??????? $value .= '--' . $this->ds;
??????? $value .= '-- 數(shù)據(jù)庫: `' . $this->database . '`' . $this->ds;
??????? $value .= '--' . $this->ds . $this->ds;
??????? $value .= '-- -------------------------------------------------------';
??????? $value .= $this->ds . $this->ds;
??????? return $value;
??? }
?
??? /**
???? * 插入表結(jié)構(gòu)
???? *
???? * @param unknown_type $table
???? * @return string
???? */
??? private function _insert_table_structure($table) {
??????? $sql = '';
??????? $sql .= "--" . $this->ds;
??????? $sql .= "-- 表的結(jié)構(gòu)" . $table . $this->ds;
??????? $sql .= "--" . $this->ds . $this->ds;
?
??????? // 如果存在則刪除表
??????? $sql .= "DROP TABLE IF EXISTS `" . $table . '`' . $this->sqlEnd . $this->ds;
??????? // 獲取詳細(xì)表信息
??????? $res = mysql_query ( 'SHOW CREATE TABLE `' . $table . '`' );
??????? $row = mysql_fetch_array ( $res );
??????? $sql .= $row [1];
??????? $sql .= $this->sqlEnd . $this->ds;
??????? // 加上
??????? $sql .= $this->ds;
??????? $sql .= "--" . $this->ds;
??????? $sql .= "-- 轉(zhuǎn)存表中的數(shù)據(jù) " . $table . $this->ds;
??????? $sql .= "--" . $this->ds;
??????? $sql .= $this->ds;
??????? return $sql;
??? }
?
??? /**
???? * 插入單條記錄
???? *
???? * @param string $table
???? * @param int $num_fields
???? * @param array $record
???? * @return string
???? */
??? private function _insert_record($table, $num_fields, $record) {
??????? // sql字段逗號分割
??????? $insert = '';
??????? $comma = "";
??????? $insert .= "INSERT INTO `" . $table . "` VALUES(";
??????? // 循環(huán)每個子段下面的內(nèi)容
??????? for($i = 0; $i < $num_fields; $i ++) {
??????????? $insert .= ($comma . "'" . mysql_escape_string ( $record [$i] ) . "'");
??????????? $comma = ",";
??????? }
??????? $insert .= ");" . $this->ds;
??????? return $insert;
??? }
?
??? /**
???? * 寫入文件
???? *
???? * @param string $sql
???? * @param string $filename
???? * @param string $dir
???? * @return boolean
???? */
??? private function _write_file($sql, $filename, $dir) {
??????? $dir = $dir ? $dir : './backup/';
??????? // 創(chuàng)建目錄
??????? if (! is_dir ( $dir )) {
??????????? mkdir ( $dir, 0777, true );
??????? }
??????? $re = true;
??????? if (! @$fp = fopen ( $dir . $filename, "w+" )) {
??????????? $re = false;
??????????? $this->_showMsg("打開sql文件失敗!",true);
??????? }
??????? if (! @fwrite ( $fp, $sql )) {
??????????? $re = false;
??????????? $this->_showMsg("寫入sql文件失敗,請文件是否可寫",true);
??????? }
??????? if (! @fclose ( $fp )) {
??????????? $re = false;
??????????? $this->_showMsg("關(guān)閉sql文件失敗!",true);
??????? }
??????? return $re;
??? }
?
??? /*
???? *
???? * -------------------------------上:數(shù)據(jù)庫導(dǎo)出-----------分割線----------下:數(shù)據(jù)庫導(dǎo)入--------------------------------
???? */
?
??? /**
???? * 導(dǎo)入備份數(shù)據(jù)
???? * 說明:分卷文件格式20120516211738_all_v1.sql
???? * 參數(shù):文件路徑(必填)
???? *
???? * @param string $sqlfile
???? */
??? function restore($sqlfile) {
??????? // 檢測文件是否存在
??????? if (! file_exists ( $sqlfile )) {
??????????? $this->_showMsg("sql文件不存在!請檢查",true);
??????????? exit ();
??????? }
??????? $this->lock ( $this->database );
??????? // 獲取數(shù)據(jù)庫存儲位置
??????? $sqlpath = pathinfo ( $sqlfile );
??????? $this->sqldir = $sqlpath ['dirname'];
??????? // 檢測是否包含分卷,將類似20120516211738_all_v1.sql從_v分開,有則說明有分卷
??????? $volume = explode ( "_v", $sqlfile );
??????? $volume_path = $volume [0];
??????? $this->_showMsg("請勿刷新及關(guān)閉瀏覽器以防止程序被中止,如有不慎!將導(dǎo)致數(shù)據(jù)庫結(jié)構(gòu)受損");
??????? $this->_showMsg("正在導(dǎo)入備份數(shù)據(jù),請稍等!");
??????? if (emptyempty ( $volume [1] )) {
??????????? $this->_showMsg ( "正在導(dǎo)入sql:<span class='imp'>" . $sqlfile . '</span>');
??????????? // 沒有分卷
??????????? if ($this->_import ( $sqlfile )) {
??????????????? $this->_showMsg( "數(shù)據(jù)庫導(dǎo)入成功!");
??????????? } else {
???????????????? $this->_showMsg('數(shù)據(jù)庫導(dǎo)入失敗!',true);
??????????????? exit ();
??????????? }
??????? } else {
??????????? // 存在分卷,則獲取當(dāng)前是第幾分卷,循環(huán)執(zhí)行余下分卷
??????????? $volume_id = explode ( ".sq", $volume [1] );
??????????? // 當(dāng)前分卷為$volume_id
??????????? $volume_id = intval ( $volume_id [0] );
??????????? while ( $volume_id ) {
??????????????? $tmpfile = $volume_path . "_v" . $volume_id . ".sql";
??????????????? // 存在其他分卷,繼續(xù)執(zhí)行
??????????????? if (file_exists ( $tmpfile )) {
??????????????????? // 執(zhí)行導(dǎo)入方法
??????????????????? $this->msg .= "正在導(dǎo)入分卷 $volume_id :<span style='color:#f00;'>" . $tmpfile . '</span><br />';
??????????????????? if ($this->_import ( $tmpfile )) {
?
??????????????????? } else {
??????????????????????? $volume_id = $volume_id ? $volume_id :1;
??????????????????????? exit ( "導(dǎo)入分卷:<span style='color:#f00;'>" . $tmpfile . '</span>失敗!可能是數(shù)據(jù)庫結(jié)構(gòu)已損壞!請嘗試從分卷1開始導(dǎo)入' );
??????????????????? }
??????????????? } else {
??????????????????? $this->msg .= "此分卷備份全部導(dǎo)入成功!<br />";
??????????????????? return;
??????????????? }
??????????????? $volume_id ++;
??????????? }
??????? }if (emptyempty ( $volume [1] )) {
??????????? $this->_showMsg ( "正在導(dǎo)入sql:<span class='imp'>" . $sqlfile . '</span>');
??????????? // 沒有分卷
??????????? if ($this->_import ( $sqlfile )) {
??????????????? $this->_showMsg( "數(shù)據(jù)庫導(dǎo)入成功!");
??????????? } else {
???????????????? $this->_showMsg('數(shù)據(jù)庫導(dǎo)入失敗!',true);
??????????????? exit ();
??????????? }
??????? } else {
??????????? // 存在分卷,則獲取當(dāng)前是第幾分卷,循環(huán)執(zhí)行余下分卷
??????????? $volume_id = explode ( ".sq", $volume [1] );
??????????? // 當(dāng)前分卷為$volume_id
??????????? $volume_id = intval ( $volume_id [0] );
??????????? while ( $volume_id ) {
??????????????? $tmpfile = $volume_path . "_v" . $volume_id . ".sql";
??????????????? // 存在其他分卷,繼續(xù)執(zhí)行
??????????????? if (file_exists ( $tmpfile )) {
??????????????????? // 執(zhí)行導(dǎo)入方法
??????????????????? $this->msg .= "正在導(dǎo)入分卷 $volume_id :<span style='color:#f00;'>" . $tmpfile . '</span><br />';
??????????????????? if ($this->_import ( $tmpfile )) {
?
??????????????????? } else {
??????????????????????? $volume_id = $volume_id ? $volume_id :1;
??????????????????????? exit ( "導(dǎo)入分卷:<span style='color:#f00;'>" . $tmpfile . '</span>失敗!可能是數(shù)據(jù)庫結(jié)構(gòu)已損壞!請嘗試從分卷1開始導(dǎo)入' );
??????????????????? }
??????????????? } else {
??????????????????? $this->msg .= "此分卷備份全部導(dǎo)入成功!<br />";
??????????????????? return;
??????????????? }
??????????????? $volume_id ++;
??????????? }
??????? }
??? }
?
??? /**
???? * 將sql導(dǎo)入到數(shù)據(jù)庫(普通導(dǎo)入)
???? *
???? * @param string $sqlfile
???? * @return boolean
???? */
??? private function _import($sqlfile) {
??????? // sql文件包含的sql語句數(shù)組
??????? $sqls = array ();
??????? $f = fopen ( $sqlfile, "rb" );
??????? // 創(chuàng)建表緩沖變量
??????? $create_table = '';
??????? while ( ! feof ( $f ) ) {
??????????? // 讀取每一行sql
??????????? $line = fgets ( $f );
??????????? // 這一步為了將創(chuàng)建表合成完整的sql語句
??????????? // 如果結(jié)尾沒有包含';'(即為一個完整的sql語句,這里是插入語句),并且不包含'ENGINE='(即創(chuàng)建表的最后一句)
??????????? if (! preg_match ( '/;/', $line ) || preg_match ( '/ENGINE=/', $line )) {
??????????????? // 將本次sql語句與創(chuàng)建表sql連接存起來
??????????????? $create_table .= $line;
??????????????? // 如果包含了創(chuàng)建表的最后一句
??????????????? if (preg_match ( '/ENGINE=/', $create_table)) {
??????????????????? //執(zhí)行sql語句創(chuàng)建表
??????????????????? $this->_insert_into($create_table);
??????????????????? // 清空當(dāng)前,準(zhǔn)備下一個表的創(chuàng)建
??????????????????? $create_table = '';
??????????????? }
??????????????? // 跳過本次
??????????????? continue;
??????????? }
??????????? //執(zhí)行sql語句
??????????? $this->_insert_into($line);
??????? }
??????? fclose ( $f );
??????? return true;
??? }
?
??? //插入單條sql語句
??? private function _insert_into($sql){
??????? if (! mysql_query ( trim ( $sql ) )) {
??????????? $this->msg .= mysql_error ();
??????????? return false;
??????? }
??? }
?
??? /*
???? * -------------------------------數(shù)據(jù)庫導(dǎo)入end---------------------------------
???? */
?
??? // 關(guān)閉數(shù)據(jù)庫連接
??? private function close() {
??????? mysql_close ( $this->db );
??? }
?
??? // 鎖定數(shù)據(jù)庫,以免備份或?qū)霑r出錯
??? private function lock($tablename, $op = "WRITE") {
??????? if (mysql_query ( "lock tables " . $tablename . " " . $op ))
??????????? return true;
??????? else
??????????? return false;
??? }
?
??? // 解鎖
??? private function unlock() {
??????? if (mysql_query ( "unlock tables" ))
??????????? return true;
??????? else
??????????? return false;
??? }
?
??? // 析構(gòu)
??? function __destruct() {
??????? if($this->db){
??????????? mysql_query ( "unlock tables", $this->db );
??????????? mysql_close ( $this->db );
??????? }
??? }
}
?>
PHP教程希望本文所述對大家的php程序設(shè)計有所幫助.
《PHP實例:php實現(xiàn)mysql備份恢復(fù)分卷處理的方法》是否對您有啟發(fā),歡迎查看更多與《PHP實例:php實現(xiàn)mysql備份恢復(fù)分卷處理的方法》相關(guān)教程,學(xué)精學(xué)透。維易PHP學(xué)院為您提供精彩教程。
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.snjht.com/jiaocheng/13170.html