一个不错的MYSQL数据库备份类,PHP版,一个文件,精简版
生活随笔
收集整理的這篇文章主要介紹了
一个不错的MYSQL数据库备份类,PHP版,一个文件,精简版
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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 string
198 */
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 $table
223 * @return string
224 */
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 $table
251 * @param int $num_fields
252 * @param array $record
253 * @return string
254 */
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 $sql
273 * @param string $filename
274 * @param string $dir
275 * @return boolean
276 */
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.sql
307 * 參數:文件路徑(必填)
308 *
309 * @param string $sqlfile
310 */
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_id
339 $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_id
371 $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 $sqlfile
397 * @return boolean
398 */
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 // 讀取每一行sql
407 $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 else
452 return false;
453 }
454
455 // 解鎖
456 private function unlock() {
457 if (mysql_query ( "unlock tables" ))
458 return true;
459 else
460 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 ?>
?
轉載于:https://www.cnblogs.com/saonian/p/9015921.html
總結
以上是生活随笔為你收集整理的一个不错的MYSQL数据库备份类,PHP版,一个文件,精简版的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ajax-jsonp
- 下一篇: Alfresco用户和权限管理