mysql 数据备份,恢复,恢复没写,这里只写了备份。。。 先暂作记录吧!
备份:表结构和数据完全分开,默认有一个文件会记录所有表的结构,然后表中数据的备份 如果超过分卷的大小则会分成多个文件,不然则一个文件,参考了别人的代码,不过写的嘛,差强 人意,以后慢慢改吧。。。
代码如下:
1 <?php 2 /* 3 * Created on 2014 4 * Link for [email protected] 5 * This is seocheck backup class 6 */ 7 class DbBackUp { 8 private $conn; 9 private $dbName; 10 private $host; 11 private $tag = '_b'; 12 //构造方法 链接数据库 13 public function __construct($host='localhost', $dbUser='root', $dbPwd='', $dbName="seocheck", $charset='utf8') { 14 @ob_start(); 15 @set_time_limit(0); 16 $this->conn = mysql_connect($host, $dbUser, $dbPwd, true); 17 if(!$this->conn) die("数据库系统连接失败!"); 18 mysql_query("set names ".$charset, $this->conn); 19 mysql_select_db($dbName, $this->conn) or die("数据库连接失败!"); 20 $this->host = $host; 21 $this->dbName = $dbName; 22 } 23 24 //获取数据库所有表名 25 public function getTableNames () { 26 $tables = array(); 27 $result = mysql_list_tables($this->dbName, $this->conn); 28 if(!$result) die('MySQL Error: ' . mysql_error()); 29 while($row = mysql_fetch_row($result)) { 30 $tables[] = $row[0]; 31 } 32 return $tables; 33 } 34 35 //获取数据库表的字段信息 36 public function getFieldsByTable ($table) { 37 $fields = array(); 38 $str = ''; 39 $res = mysql_query("SHOW CREATE TABLE `{$table}`", $this->conn); 40 if(!$res) die('MySQL Error: ' . mysql_error()); 41 while($rows = mysql_fetch_assoc($res)) { 42 $str = str_replace("CREATE TABLE `{$table}` (", "", $rows['Create Table']);//DROP TABLE IF EXISTS `{$table}`\n 43 $str = "--\n-- Table structure for table `{$table}`\n--\n\nCREATE TABLE IF NOT EXISTS `{$table}` ( ".$str; 44 $str = str_replace(",", ", ", $str); 45 $str = str_replace("`) ) ENGINE=InnoDB ", "`)\n ) ENGINE=InnoDB ", $str); 46 $str .=";\n\n"; 47 //$str = $str.";\n\n--\n-- Dumping data for table `{$table}`\n--\n\n"; 48 $fields[$rows['Table']] = $str; 49 } 50 return $fields; 51 } 52 53 //获取表中的数据 54 public function getDataByTable($table) { 55 $data = array(); 56 $str = ''; 57 $res = mysql_query("SELECT * FROM `{$table}`", $this->conn); 58 if(!$res) die('MySQL Error: ' . mysql_error()); 59 while($rows = mysql_fetch_assoc($res)) { 60 if(!empty($rows)) { 61 $data[] = $rows; 62 } 63 } 64 $keys = array_keys($data[0]); 65 foreach ($keys as $k=>$v) { 66 $keys[$k] = '`'.$v.'`'; 67 } 68 $key = join(', ', $keys); 69 $str = "INSERT INTO `{$table}` ({$key}) VALUES\n"; 70 foreach ($data as $k=>$v) { 71 $str.="("; 72 while (list($key, $val) = each($v)) { 73 if(!is_numeric($val)) { 74 $str.= "'".$val."', "; 75 } else { 76 $str.= $val.', '; 77 } 78 } 79 $str = substr($str, 0, -2);// 后边有空格 所以从-2 开始截取 80 if($k+1 == count($data)) { 81 $str.=");\n\n-- --------------------------------------------------------\n\n"; 82 } else { 83 $str.="),\n"; 84 } 85 } 86 return $str; 87 } 88 89 //备份数据库 90 public function getBackUpDataByTable ($tables, $path='', $fileName = 'seocheck', $subsection = '2') { 91 if(empty($tables)) $this->_showMsg('未能指定要备份的表!!!', true); 92 $page = 0;//卷数 93 $path = empty($path) ? $_SERVER['DOCUMENT_ROOT'].'/core/Runtime/Data/'.$fileName.'Demo/' : $path; 94 if(!file_exists($path)) { 95 mkdir($path, 0777, true); 96 } 97 $mysql_info = $this->_retrieve(); 98 $fieldsByTable = array(); 99 if(is_array($tables)) { 100 $this->_showMsg('开始备份,数据正在初始化中,请勿关闭浏览器...'); 101 $fw = $this->writeFileByBackUpData($path.$this->dbName.'_table.sql', $mysql_info, $method="ab+"); 102 if($fw !== false) { 103 $this->_showMsg('备份数据库基本信息成功。。。'); 104 } 105 foreach ($tables as $table) { 106 $tableInfo = $this->getFieldsByTable($table); 107 if(!empty($tableInfo)) { 108 $this->_showMsg('获取表['.$table.']结构成功。。。'); 109 $fw = $this->writeFileByBackUpData($path.$this->dbName.'_table.sql', $tableInfo[$table], $method="ab+"); 110 if($fw === false) { 111 $this->_showMsg('备份表['.$table.']结构失败。。。', true); 112 } else { 113 $this->_showMsg('备份表['.$table.']结构成功,开始获取数据。。。'); 114 }; 115 } else { 116 $this->_showMsg('获取数据库['.$this->dbName.']表结构失败,请稍后再试!。。。', true); 117 } 118 $this->_insertSqlByTableForAll($path, $table, $subsection); 119 } 120 } else { 121 $this->_showMsg('开始备份,数据正在初始化中,请勿关闭浏览器...'); 122 $tableInfo = $this->getFieldsByTable($tables); 123 if(!empty($tableInfo)) { 124 $this->_showMsg('获取表['.$tables.']结构成功。。。'); 125 $fw = $this->writeFileByBackUpData($path.$this->dbName.'_'.$tables.'_table.sql', $mysql_info.$tableInfo[$tables]); 126 if($fw === false) { 127 $this->_showMsg('备份表['.$tables.']结构失败。。。', true); 128 } else { 129 $this->_showMsg('备份表['.$tables.']结构成功,开始获取数据。。。'); 130 } 131 } else { 132 $this->_showMsg('获取表['.$tables.']结构失败,请稍后再试!。。。', true); 133 } 134 $res = $this->_insertSqlByTableForAll($path, $tables, $subsection); 135 } 136 } 137 138 //数据库基本信息 139 private function _retrieve() { 140 $backUp = ''; 141 $backUp .= '--' . "\n"; 142 $backUp .= '-- MySQL database dump' . "\n"; 143 $backUp .= '-- Created by DbBackUp class, Power By chujiu. ' . "\n"; 144 $backUp .= '--' . "\n"; 145 $backUp .= '-- 主机: ' . $this->host . "\n"; 146 $backUp .= '-- 生成日期: ' . date ( 'Y' ) . ' 年 ' . date ( 'm' ) . ' 月 ' . date ( 'd' ) . ' 日 ' . date ( 'H:i' ) . "\n"; 147 $backUp .= '-- MySQL版本: ' . mysql_get_server_info () . "\n"; 148 $backUp .= '-- PHP 版本: ' . phpversion () . "\n"; 149 $backUp .= "\n\n"; 150 $backUp .= "SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';\n"; 151 $backUp .= "SET time_zone = '+00:00';\n\n"; 152 $backUp .= "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;\n"; 153 $backUp .= "/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;\n"; 154 $backUp .= "/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;\n"; 155 $backUp .= "/*!40101 SET NAMES utf8*/;\n\n"; 156 $backUp .= "--\n-- Database: `{$this->dbName}`\n--\n\n-- --------------------------------------------------------\n\n"; 157 return $backUp; 158 } 159 160 /** 161 * 插入单条记录 162 * 163 * @param string $row 164 */ 165 private function _insertSql($row, $table) { 166 // sql字段逗号分割 167 $insert = ''; 168 $insert .= "INSERT INTO `" . $table . "` VALUES("; 169 foreach($row as $key=>$val) { 170 $insert .= "'".$val."',"; 171 } 172 $insert = substr($insert, 0 ,-1); 173 $insert .= ");" . "\n"; 174 return $insert; 175 } 176 177 /** 178 * 生成一个表的inser语句 179 * @param string $table 180 * @param string $subsection 分卷大小 181 */ 182 private function _insertSqlByTableForAll($path, $table, $subsection) { 183 $i = 0; 184 $insertSqlByTable = ''; 185 $res = mysql_query("SELECT * FROM `{$table}`", $this->conn); 186 if(!$res) die('MySQL Error: ' . mysql_error()); 187 while($rows = mysql_fetch_assoc($res)) { 188 $insertSqlByTable .= $this->_insertSql($rows, $table); 189 $size = strlen($insertSqlByTable); 190 if($size > $subsection*1024*1024) { 191 $fw = $this->writeFileByBackUpData($path.$table.$i.$this->tag.'.sql', $insertSqlByTable); 192 if($fw === false) $this->_showMsg('数据库表['.$table.'],卷 '.$i.' 写入文件失败,请稍后再试!!!',true); 193 $this->_showMsg('数据库表['.$table.'],卷 '.$i.' 备份成功!备份文件:[ '.$path.$table.$i.$this->tag.'.sql ]'); 194 $insertSqlByTable = ''; 195 $i+=1; 196 } 197 } 198 // insertSqlByTable大小不够分卷大小 199 if ($insertSqlByTable != "") { 200 $fw = $this->writeFileByBackUpData($path.$table.$this->tag.'.sql', $insertSqlByTable); 201 if($fw === false) $this->_showMsg('数据库表['.$table.']写入文件失败,请稍后再试!!!备份文件:[ '.$path.$table.$this->tag.'.sql ]',true); 202 $this->_showMsg('数据库表['.$table.'] 备份成功!备份文件:[ '.$path.$table.$this->tag.'.sql ]'); 203 } 204 $this->_showMsg('数据库表['.$table.']全部备份成功!'); 205 } 206 207 // 写入文件 208 public function writeFileByBackUpData($fileName, $data, $method="rb+", $iflock=1, $check=1, $chmod=1){ 209 $check && @strpos($fileName, '..')!==false && exit('Forbidden'); 210 @touch($fileName); 211 $handle = @fopen($fileName, $method); 212 if($iflock) { 213 @flock($handle,LOCK_EX); 214 } 215 $fw = @fwrite($handle,$data); 216 if($method == "rb+") ftruncate($handle, strlen($data)); 217 fclose($handle); 218 $chmod && @chmod($fileName,0777); 219 return $fw; 220 } 221 222 /** 223 * path: 生成压缩包的路径 224 * fileName : 要压缩的文件名 通常和path 同一目录 225 */ 226 public function createZipByBackUpFile($path) { 227 $db_base_files = $this->getFileByBackUpDir($path); 228 if(!empty($db_base_files)) { 229 $zip = new ZipArchive; 230 if($zip->open($path.$this->dbName.date('Ymd').'.zip', ZipArchive::CREATE | ZIPARCHIVE::OVERWRITE) !== true) 231 die ("cannot open".$this->dbName.date('Ymd')."zip for writing."); 232 foreach ($db_base_files as $key => $value) { 233 if(is_file($value)) { 234 $file_name = basename($value); 235 $info[] = $zip->addFile($value, $file_name);// 避免压缩包里有文件的路径 236 } 237 } 238 $zip->close(); 239 if(file_exists($path.$this->dbName.date('Ymd').'.zip')) 240 foreach ($db_base_files as $val) { 241 unlink($val); 242 } 243 if(count(array_filter($info)) > 0) return true; 244 } 245 return false; 246 } 247 248 //获取文件 249 public function getFileByBackUpDir($path) { 250 $info = array(); 251 $db_base_files = array(); 252 if( @file_exists($path) && is_dir($path) ) { 253 if ($dh = opendir($path)) { 254 while (($file = readdir($dh)) !== false) { 255 if($file != '.' && $file != '..') { 256 if( strripos($file, 'seocheck') !== false ) { 257 $db_base_files[] = $path.$file; 258 } 259 } 260 } 261 closedir($dh); 262 } 263 } 264 return $db_base_files; 265 } 266 267 /** 268 * @path: 生成压缩包的路径 269 * @fileName : 要解压的文件名 默认解压到path 目录 270 */ 271 public function uncompressZip($path, $zipName) { 272 $path = empty($path) ? $_SERVER['DOCUMENT_ROOT'].'/core/Runtime/Data/' : $path; 273 $zip = new ZipArchive; 274 if ($zip->open($path.$zipName) === TRUE) { 275 $zip->extractTo($path); 276 $zip->close(); 277 return true; 278 } else { 279 return false; 280 } 281 } 282 283 //导入数据库 284 public function importingDataBySqlFile () { 285 286 } 287 288 // 及时输出信息 289 private function _showMsg($msg,$err=false){ 290 if($err === true) { 291 echo "<p style='font-size:14px;'><span style='color:red;'>ERROR: --- " . $msg . "</span></p>";exit; 292 } 293 echo "<p style='font-size:14px;'><span style='color:green;'>OK: --- " . $msg . "</span></p>"; 294 } 295 296 // 锁定数据库,以免备份或导入时出错 297 private function lock($table, $op = "WRITE") { 298 if (mysql_query ( "lock tables " . $table . " " . $op )) 299 return true; 300 else 301 return false; 302 } 303 304 // 解锁 305 private function unlock() { 306 if (mysql_query ( "unlock tables" )) 307 return true; 308 else 309 return false; 310 } 311 312 // 析构 313 public function __destruct() { 314 if($this->conn){ 315 mysql_query ( "unlock tables", $this->conn ); 316 mysql_close ( $this->conn ); 317 } 318 } 319 } 320 ?>