一个thinkphp操作类,用来导出mysql数据和导入备份<?php <br />
class DBAction extends CommonAction{<br>
private $ds = "\n\r\n\r";<br>
// 每条sql语句的结尾符<br>
public $sqlEnd = ";";<br>
public function index(){<br>
$M = M();<br>
$tabs = $M->query('SHOW TABLE STATUS');<br>
$total = 0;<br>
foreach ($tabs as $k => $v) {<br>
$tabs[$k]['size'] = byteFormat($v['Data_length'] + $v['Index_length']);<br>
$total+=$v['Data_length'] + $v['Index_length'];<br>
}<br>
//echo __APP__."/Public/data/";<br>
// echo $this->export($tablename="");<br>
// echo $this->restore("./Public/backup/20130704091642_tao_group_v1.sql");<br>
$this->assign("list", $tabs);<br>
$this->assign("total", byteFormat($tota ));<br>
$this->assign("tables", count($tabs));<br>
$this->display();<br>
}<br>
public function import(){<br>
//echo C("DB_BACKUP");<br>
//print_r(glob(C("DB_BACKUP")."*.sql"))<br>
foreach (glob(C("DB_BACKUP")."*.sql") as $filename) {<br>
$arr[]=array("filename"=>$filename,"size"=>filesize($filename));<br>
}<br>
// if(!empty($_GET["file"])){<br>
// $this->restore(I("file"));<br>
// }<br>
$this->assign("list", $arr);<br>
$this->display(); <br>
}<br>
public function truncate(){<br>
$table=I("table");<br>
if(!empty($table)){<br>
$M = M();<br>
$result = $M->query('TRUNCATE TABLE '.$table);<br>
<br>
if(empty($result)){<br>
$this->success("清空表成功!");<br>
}else{<br>
$this->error("清空表失败!");<br>
}<br>
}<br>
}<br>
public function delete(){<br>
$table=I("table");<br>
if(!empty($table)){<br>
$M = M();<br>
$result = $M->query('DROP TABLE '.$table);<br>
<br>
if($result){<br>
$this->success("删除表成功!");<br>
}else{<br>
$this->error("删除表失败!");<br>
}<br>
}<br>
}<br>
/**<br>
* getTables 获取数据库表列表<br>
* @return array $tables 返回结果数组 <br>
*/<br>
public function getTables() {<br>
$M = M();<br>
$res = $M->query ( "SHOW TABLES;" );<br>
$tables = array ();<br>
foreach ( $res as $row ) {<br>
<br>
foreach ($row as $v){<br>
$tables[]=$v;<br>
}<br>
}<br>
return $tables;<br>
}<br>
/**<br>
* 插入数据库备份基础信息<br>
*<br>
* @return string<br>
*/<br>
private function _base() {<br>
$value = '';<br>
$value .= '-- MySQL database dump' . $this->ds;<br>
$value .= '-- Created by DBAction class, Power By TaoTao. ' . $this->ds;<br>
$value .= '-- http://blog.kisscn.com ' . $this->ds;<br>
$value .= '--' . $this->ds;<br>
$value .= '-- 主机: ' . $this->host . $this->ds;<br>
$value .= '-- 生成日期: ' . date ( 'Y' ) . ' 年 ' . date ( 'm' ) . ' 月 ' . date ( 'd' ) . ' 日 ' . date ( 'H:i' ) . $this->ds;<br>
$value .= '-- MySQL版本: ' . mysql_get_server_info () . $this->ds;<br>
$value .= '-- PHP 版本: ' . phpversion () . $this->ds;<br>
$value .= $this->ds;<br>
$value .= '--' . $this->ds;<br>
$value .= '-- 数据库: `' . C("DB_NAME") . '`'. $this->ds;<br>
$value .= '--' . $this->ds ;<br>
$value .= '-- -------------------------------------------------------';<br>
$value .= $this->ds . $this->ds;<br>
return $value;<br>
}<br>
/**<br>
* 插入表结构<br>
*<br>
* @param unknown_type $table <br>
* @return string<br>
*/<br>
private function _insert_table_structure($table) {<br>
$sql = '';<br>
$sql .= "--" . $this->ds;<br>
$sql .= "-- 表的结构" . $table .$this->ds."--" .$this->ds;<br>
$M = M();<br>
// 如果存在则删除表<br>
$sql .= "DROP TABLE IF EXISTS `" . $table . '`' . $this->sqlEnd . $this->ds;<br>
// 获取详细表信息<br>
$res = $M->query ( 'SHOW CREATE TABLE `' . $table . '`' );<br>
$sql .= $res [0]["Create Table"];<br>
$sql .= $this->sqlEnd . $this->ds;<br>
// 加上<br>
$sql .= $this->ds;<br>
$sql .= "--" . $this->ds;<br>
$sql .= "-- 转存表中的数据 " . $table . $this->ds;<br>
$sql .= "--" . $this->ds;<br>
$sql .= $this->ds;<br>
return $sql;<br>
}<br>
<br>
/**<br>
* 插入语句构造<br>
*<br>
* @param string $table <br>
* @return string<br>
*/<br>
private function _insert_record($table) {<br>
// sql字段逗号分割<br>
<br>
$M=M();<br>
$res = $M->query ( 'select * FROM `' . $table . '`' ); <br>
// 循环每个子段下面的内容<br>
foreach ($res as $val){<br>
$comma = 0;<br>
$insert .= "INSERT INTO `" . $table . "` VALUES(";<br>
foreach ($val as $v){<br>
$insert.=$comma == 0 ? "" : ",";<br>
$insert.= ( "'" . mysql_escape_string ( $v ) . "'");<br>
$comma++;<br>
<br>
}<br>
$insert .= ");" . $this->ds;<br>
<br>
}<br>
<br>
return $insert;<br>
}<br>
<br>
/**<br>
* 写入文件<br>
*<br>
* @param string $sql <br>
* @param string $filename <br>
* @param string $dir <br>
* @return boolean<br>
*/<br>
private function _write_file($sql, $filename, $dir) {<br>
$dir = C("DB_BACKUP");<br>
// 创建目录<br>
if (! is_dir ( $dir )) {<br>
mkdir ( $dir, 0777, true );<br>
}<br>
$re = true;<br>
if (! @$fp = fopen ( $dir . $filename, "w+" )) {<br>
$re = false;<br>
$msg .= "打开文件失败!";<br>
}<br>
if (! @fwrite ( $fp, $sql )) {<br>
$re = false;<br>
$msg .= "写入文件失败,请文件是否可写";<br>
}<br>
if (! @fclose ( $fp )) {<br>
$re = false;<br>
$msg .= "关闭文件失败!";<br>
}<br>
return $re;<br>
}<br>
/**<br>
* 数据库备份<br>
* 参数:备份哪个表(可选),备份目录(可选,默认为backup),分卷大小(可选,默认2048,即2M)<br>
*<br>
* @param string $dir <br>
* @param int $size <br>
* @param array $tablename <br>
*/<br>
public function export() {<br>
$tablename=I("table");<br>
$dir = C("DB_BACKUP");<br>
// 创建目录<br>
if (! is_dir ( $dir )) {<br>
mkdir ( $dir, 0777, true ) or die ( '创建文件夹失败' );<br>
}<br>
$size = C("DB_BACKUP_SIZE");<br>
$sql = '';<br>
$tables=explode(",", $tablename);<br>
//print_r($tables);<br>
$M=M();<br>
if(!empty($tablename)){<br>
foreach ($tables as $value) {<br>
$msg .= '正在备份表' . $value . '<br>';<br>
// 插入文件头信息<br>
$sql = $this->_base ();<br>
// 插入表结构信息<br>
$sql .= $this->_insert_table_structure ( $value );<br>
// 文件名前缀<br>
$filename = date ( 'YmdHis' ) . "_" . $value;<br>
// 分卷标识<br>
$p = 1;<br>
$sql .= $this->_insert_record ( $value);<br>
// 如果大于分卷大小,则写入文件<br>
//$msg.="文件大小为:".strlen ( $sql );<br>
if (strlen ( $sql ) >= $size * 1024) {<br>
$file = $filename . "_v" . $p . ".sql";<br>
if ($this->_write_file ( $sql, $file, $dir )) {<br>
$msg .= "表-" . $value . "-卷-" . $p . '<br>';<br>
$msg.= "-数据备份完成,生成备份文件 <span>$dir$filename</span><br>";<br>
} else {<br>
$msg .= "备份表-" . $value . "-失败<br>";<br>
return false;<br>
}<br>
// 下一个分卷<br>
$p ++;<br>
// 重置$sql变量为空,重新计算该变量大小<br>
$sql = "";<br>
}else{<br>
// sql大小不够分卷大小<br>
if ($sql != "") {<br>
$filename .= ".sql";<br>
if ($this->_write_file ( $sql, $filename, $dir )) {<br>
$msg .= "表-" . $value . "-卷-" . $p. '<br>'. "-数据备份完成,生成备份文件 <span>$dir$filename</span><br>";<br>
} else {<br>
$msg .= "备份卷-" . $p . "-失败<br>";<br>
return false;<br>
}<br>
}<br>
}<br>
}<br>
}else{<br>
// 备份全部表<br>
if ($tables = $M->query( "show table status from " . C("DB_NAME") )) {<br>
$msg .= "读取数据库结构成功!<br>";<br>
} else {<br>
exit ( "读取数据库结构失败!<br>" );<br>
}<br>
// 插入dump信息<br>
$sql .= $this->_base ();<br>
// 文件名前面部分<br>
$filename = date ( 'YmdHis' ) . "_all";<br>
// 查出所有表<br>
$tables = $M->query ( 'SHOW TABLES' );<br>
// 第几分卷<br>
$p = 1;<br>
// 循环所有表<br>
foreach ( $tables as $value) {<br>
foreach ($value as $v) {<br>
<br>
// 获取表结构<br>
$sql .= $this->_insert_table_structure ( $v );<br>
// 单条记录<br>
$sql .= $this->_insert_record ( $v );<br>
}<br>
<br>
}<br>
// 如果大于分卷大小,则写入文件<br>
if (strlen ( $sql ) >= $size * 1024) {<br>
<br>
$file = $filename . "_v" . $p . ".sql";<br>
// 写入文件<br>
if ($this->_write_file ( $sql, $file, $dir )) {<br>
$this->msg .= "-卷-" . $p . "-数据备份完成,生成备份文件<span>$dir$file</span><br>";<br>
} else {<br>
$this->msg .= "备份卷-" . $p . "-失败<br>";<br>
return false;<br>
}<br>
// 下一个分卷<br>
$p ++;<br>
// 重置$sql变量为空,重新计算该变量大小<br>
//$sql = "";<br>
}<br>
// sql大小不够分卷大小<br>
if ($sql != "") {<br>
$filename .= ".sql";<br>
if ($this->_write_file ( $sql, $filename, $dir )) {<br>
$msg .= "数据库-" . C("DB_NAME") . "-卷-" . $p. '<br>'. "-数据备份完成,生成备份文件 <span>$dir$filename</span><br>";<br>
} else {<br>
$msg .= "备份卷-" . $p . "-失败<br>";<br>
return false;<br>
}<br>
}<br>
}<br>
echo $msg; <br>
}<br>
<br>
/**<br>
* 导入备份数据<br>
* 说明:分卷文件格式20120516211738_all_v1.sql<br>
* 参数:文件路径(必填)<br>
*<br>
* @param string $sqlfile <br>
*/<br>
function restore($file) {<br>
$sqlfile=C("DB_BACKUP").$file;<br>
<br>
// 检测文件是否存在<br>
if (! file_exists ( $sqlfile )) {<br>
exit ( "文件不存在!请检查" );<br>
}<br>
$this->lock ( C("DB_NAME") );<br>
// 获取数据库存储位置<br>
$sqlpath = pathinfo ( $sqlfile );<br>
// $this->sqldir = $sqlpath ['dirname'];<br>
// 检测是否包含分卷,将类似20120516211738_all_v1.sql从_v分开,有则说明有分卷<br>
$volume = explode ( "_v", $sqlfile );<br>
$volume_path = $volume [0];<br>
$msg .= "请勿刷新及关闭浏览器以防止程序被中止,如有不慎!将导致数据库结构受损<br>";<br>
$msg .= "正在导入备份数据,请稍等!<br>";<br>
if (empty ( $volume [1] )) {<br>
$msg .= "正在导入sql:<span>" . $sqlfile . '</span><br>';<br>
// 没有分卷<br>
if ($this->_import ( $sqlfile )) {<br>
echo $msg .= "数据库导入成功!";<br>
//$this->success("数据库导入成功!");<br>
} else {<br>
exit ( '数据库导入失败!' );<br>
}<br>
} else {<br>
// 存在分卷,则获取当前是第几分卷,循环执行余下分卷<br>
$volume_id = explode ( ".sq", $volume [1] );<br>
// 当前分卷为$volume_id<br>
$volume_id = intval ( $volume_id [0] );<br>
while ( $volume_id ) {<br>
$tmpfile = $volume_path . "_v" . $volume_id . ".sql";<br>
// 存在其他分卷,继续执行<br>
if (file_exists ( $tmpfile )) {<br>
// 执行导入方法<br>
$msg .= "正在导入分卷 $volume_id :<span>" . $tmpfile . '</span><br>';<br>
if ($this->_import ( $tmpfile )) {<br>
<br>
} else {<br>
$volume_id = $volume_id ? $volume_id :1;<br>
exit ( "导入分卷:<span>" . $tmpfile . '</span>失败!可能是数据库结构已损坏!请尝试从分卷1开始导入' );<br>
}<br>
} else {<br>
$msg .= "此分卷备份全部导入成功!<br>";<br>
echo $msg;<br>
}<br>
$volume_id ++;<br>
}<br>
}<br>
}<br>
/**<br>
* 将sql导入到数据库(普通导入)<br>
*<br>
* @param string $sqlfile <br>
* @return boolean<br>
*/<br>
private function _import($sqlfile) {<br>
// sql文件包含的sql语句数组<br>
$sqls = array ();<br>
$f = fopen ( $sqlfile, "rb" );<br>
// 创建表缓冲变量<br>
$create_table = '';<br>
while ( ! feof ( $f ) ) {<br>
// 读取每一行sql<br>
$line = fgets ( $f );<br>
// 这一步为了将创建表合成完整的sql语句<br>
// 如果结尾没有包含';'(即为一个完整的sql语句,这里是插入语句),并且不包含'ENGINE='(即创建表的最后一句)<br>
if (! preg_match ( '/;/', $line ) || preg_match ( '/ENGINE=/', $line )) {<br>
// 将本次sql语句与创建表sql连接存起来<br>
$create_table .= $line;<br>
// 如果包含了创建表的最后一句<br>
if (preg_match ( '/ENGINE=/', $create_table)) {<br>
//执行sql语句创建表<br>
$this->_insert_into($create_table);<br>
// 清空当前,准备下一个表的创建<br>
$create_table = '';<br>
}<br>
// 跳过本次<br>
continue;<br>
}<br>
//执行sql语句<br>
$this->_insert_into($line);<br>
}<br>
fclose ( $f );<br>
return true;<br>
}<br>
//插入单条sql语句<br>
private function _insert_into($sql){<br>
$M=M();<br>
if (! $M->query( trim ( $sql ) )) {<br>
$msg .= mysql_error ();<br>
return false;<br>
}<br>
}<br>
// 锁定数据库,以免备份或导入时出错<br>
private function lock($tablename, $op = "WRITE") {<br>
$M=M();<br>
if ($M->query( "lock tables " . $tablename . " " . $op ))<br>
return true;<br>
else<br>
return false;<br>
}<br>
<br>
// 解锁<br>
private function unlock() {<br>
$M=M();<br>
if ($M->query ( "unlock tables" ))<br>
return true;<br>
else<br>
return false;<br>
}<br>
<br>
}<br>
/**<br>
+----------------------------------------------------------<br>
* 功能:计算文件大小<br>
+----------------------------------------------------------<br>
* @param int $bytes<br>
+----------------------------------------------------------<br>
* @return string 转换后的字符串<br>
+----------------------------------------------------------<br>
*/<br>
function byteFormat($bytes) {<br>
$sizetext = array(" B", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB");<br>
return round($bytes / pow(1024, ($i = floor(log($bytes, 1024)))), 2) . $sizetext[$i];<br>
}
备份效果:
AD:真正免费,域名+虚机+企业邮箱=0元