方法一:
query($sql); } //將生成的臨時備份文件合在一起 $outfile = date("Y-m-d").".sql"; if(file_exists($dbdir.$outfile)) @unlink($dbdir.$outfile); $fpr = fopen($dbdir.$outfile, "a"); foreach($txtname as $txt){ if(file_exists($dbdir.$txt)){ //讀取臨時備份文件 $tdata = readfiles($dbdir.$txt); //生成備份文件 $tbl = explode(".", $txt); $str = "`".$tbl[0]."`{{".$tdata."}}"; if(fwrite($fpr, $str)){ echo $tbl[0]."...寫入 $outfile 成功! "; }else{ echo $tbl[0]."...寫入 $outfile 失敗! "; } @unlink($dbdir.$txt); } } fclose($fpr); }else{//恢復數據 $tdata = readfiles($dbdir.$_POST["sqlfile"]); preg_match_all("/`(.*)`{{(.*)}}/isU", $tdata, $data_ar); foreach($data_ar[1] as $k => $tt){ if(empty($data_ar[2][$k])) continue; $tfile = $dbdir.$tt.".txt"; $fp = fopen($tfile, "w"); if(fwrite($fp, $data_ar[2][$k])){ //清空表 $sql = "TRUNCATE TABLE `$tt`"; $db->query($sql); //重新裝入數據 $sql = "LOAD DATA LOW_PRIORITY INFILE '".$dbdir.$tt.".txt"."' INTO TABLE `$tt`"; if($db->query($sql)){ fclose($fp); echo $tt."表數據恢復成功! "; unlink($dbdir.$tt.".txt"); }else{ echo $tt."表數據恢復失敗! "; } } } //echo $tdata; //print_r($data_ar); //exit; }} /* * 讀取文件內容 * 參數 $file 為文件名及完整路徑 * 返回文件內容 */ function readfiles($file){ $tdata = ""; $fp = fopen($file, "r"); if(filesize($file) <= 0) return; while($data = fread($fp, filesize($file))){ $tdata .= $data; } fclose($fp); return $tdata; }?> |
方法二:
想在PHP后臺管理直接能夠備份數據庫,于是想呀想,一直沒有什么思路,一開始是考慮用php來訪問服務器安裝mysql的目錄,比如 /usr/local/mysql/data目錄,直接把下面對應的文件進行備份,但是出現了問題:
第一、運行php的是apche的用戶,比如是nobody,那么它一般是沒有權限訪問/usr/local/mysql/data目錄的
第二、就算能夠訪問,那么你如何能夠把/usr/local/mysql/data目錄下的文件拷貝出來呢?因為mysql在運行的時候是不運行訪問的,那么nobody用戶有權限停止mysql的服務,不可能!
越想越不對勁,沒有辦法,看能不能從php操作數據庫入手,于是就去看了下phpMyadmin和Discuz!的代碼,呵呵,于是偷抄了Discuz!的代碼,形成了如下備份數據庫的方法。(在這里感謝Discuz!的開發者)
備份數據庫有兩種方式,一種是只備份數據庫的結構,一種把是結構和所有的數據都備份出來,當然是第二種方法好啦,不過我為了考慮可能的需求就都作啦。
/****** 備份數據庫結構 ******//*函數名稱:table2sql()函數功能:把表的結構轉換成為SQL函數參數:$table: 要進行提取的表名返 回 值:返回提取后的結果,SQL集合函數作者:heiyeluren*/function table2sql($table) { global $db; $tabledump = "DROP TABLE IF EXISTS $table;"; $createtable = $db->query("SHOW CREATE TABLE $table"); $create = $db->fetch_row($createtable); $tabledump .= $create[1].";"; return $tabledump;}/****** 備份數據庫結構和所有數據 ******//*函數名稱:data2sql()函數功能:把表的結構和數據轉換成為SQL函數參數:$table: 要進行提取的表名返 回 值:返回提取后的結果,SQL集合函數作者:heiyeluren*/function data2sql($table) { global $db; $tabledump = "DROP TABLE IF EXISTS $table;"; $createtable = $db->query("SHOW CREATE TABLE $table"); $create = $db->fetch_row($createtable); $tabledump .= $create[1].";"; $rows = $db->query("SELECT * FROM $table"); $numfields = $db->num_fields($rows); $numrows = $db->num_rows($rows); while ($row = $db->fetch_row($rows)) { $comma = ""; $tabledump .= "INSERT INTO $table VALUES("; for($i = 0; $i < $numfields; $i++) { $tabledump .= $comma."'".mysql_escape_string($row[$i])."'"; $comma = ","; } $tabledump .= ");"; } $tabledump .= ""; return $tabledump;}/****** 具體實現操作 ******/好,我們既然把代碼都寫出來了,那么我們如何在具體的程序種去實現備份呢,我們看下面的代碼。/* 備份數據庫 */// 注意:我們一下的數據庫操作采用了phplib的DB類// 定義要保存的數據表、前綴、保存到何處$tables = array('us_sort', 'us_download', 'us_article', 'us_guestbook'); //定義要保存的數據表,一個數組$prefix = 'us_'; // 要保存的.sql文件的前綴$saveto = 'server'; // 要保存到什么地方,是本地還是服務器上,默認是服務器$back_mode = 'all'; // 要保存的方式,是全部備份還是只保存數據庫結構$admin = 'heiyeluren'; //管理員名稱$admin_email = '[email protected]'; // 管理員郵箱// 定義數據保存的文件名$local_filename = $prefix.date('Ymd_His').'.sql"';if (!$filename) { $filename = $db_backup_path . $prefix . date('Ymd_His_'). create_check_code(4) . ".sql"; }$filename = $prefix.date(Ymd_His). create_check_ code(6).".sql"; // 保存在服務器上的文件名// 注意后面的create_check_code()函數,這是一個生成隨機碼的函數,詳細可以參考:// http://blog.csdn.net/heiyeshuwu/archive/2005/01/26/268446.aspx// 獲取數據庫結構和數據內容foreach($tables as $table) { if ($back_mode == 'all') { $sqldump .= data2sql($table); } if ($back_mode == 'table') { $sqldump .= table2sql($table); }}// 如果數據內容不是空就開始保存if(trim($sqldump)) { // 寫入開頭信息 $sqldump = "# --------------------------------------------------------". "# 數據表備份". "#". "# 服務器: $db->Host". "# 數據庫:$db->Database". "# 備份編號: ". create_sess_id() ."". // 這里有一個生成session id的函數 "# 備份時間: ".time_to_date('',6)."". // 這里就是獲取當前時間的函數 "#". "# 管理員:$admin ($admin_email)". // 管理員的用戶名和郵箱地址 "# $copyright". "# --------------------------------------------------------". $sqldump; // 保存到本地 if($saveto == "local") { ob_end_clean(); header('Content-Encoding: none'); header('Content-Type: '.(strpos($HTTP_SERVER_VARS['HTTP_USER_AGENT'], 'MSIE') ? 'application/octetstream' : 'application/octet-stream')); header('Content-Disposition: '.(strpos($HTTP_SERVER_VARS['HTTP_USER_AGENT'], 'MSIE') ? 'inline; ' : 'attachment; ').'filename="'.$local_filename); header('Content-Length: '.strlen($sqldump)); header('Pragma: no-cache'); header('Expires: 0'); echo $sqldump; } // 保存到本地結束 // 保存在服務器 if($saveto == "server") { if($filename != "") { @$fp = fopen($filename, "w+"); if ($fp) { @flock($fp, 3); if(@!fwrite($fp, $sqldump)) { @fclose($fp); exit_msg("數據文件無法保存到服務器,請檢查目錄屬性你是否有寫的權限。"); } else { exit_msg("數據成功備份至服務器 $filename 中。"); } } else { exit_msg("無法打開你指定的目錄". $filename .",請確定該目錄是否存在,或者是否有相應權限"); } } else { exit_msg("您沒有輸入備份文件名,請返回修改。"); } } // 保存到服務器結束}else{ exit_msg("數據表沒有任何內容");}/* 備份數據庫結束 */ |
呵呵,基本上這樣就結束了,然后涉及到的一個問題是如何把數據恢復到數據庫中,我想這個是不復雜的,但是最好能夠滿足有從客戶端和從服務器恢復數據的功能。
作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
※以上資訊由網路資料整理而成,若有遺誤概以來源為準,本站不負任何相關責任。
※如果您認為網站上資訊侵犯了您的版權,請告訴我們
按這裡,我們將即時將您的版權資料移除。