准备
开发环境:windows10 + phpstorm + xampp
使用的相关组件 前端:AceAdmin后台管理模版 + Jquery UI 后端:thinkphp3.2.2版本
前言:小弟初来乍道,望有问题可以互相交流,互相进步,有更好的方法可以互相交流哈。今天在网上查找有关于 网页版的mysql备份和还原的相关资料,学习一下,但是百度了不少,反反复复都是复制来复制去的,代码相比较混乱,让我看的很费解,所以我打算自己来写个。还有就是阅读本文章需要有PHP的底子和对thinkphp框架比较了解,同时需要在mysql上面也需要一些了解,特别是sql语句。
————————————我是可爱的分割线————————————
开始
先来波效果图感受下,这次先写备份,下次有时间再更新
步骤一:得到你需要操作的本地数据库中的表的列表,下面贴上代码更直观 ,有些注释大神直接忽略,给有需要的人易于理解。
public function backupAndExport()
{
$dataName= C("DB_NAME"); //获取配置文件中配置的数据库名称
$this->assign("backupModuleCurrent","open active");//Ace框架显示效果,可忽略代码
$sql="SHOW TABLE STATUS FROM ".$dataName;//列出数据库所有的表
$tableList= M()->query($sql);
$databaseCount='';//统计数据库大小初始化变量
//组装变量 将表大小data_length 和 碎片data_free转化为kb大小
foreach($tableList as &$tv)
{
$tv['table_size'] = intval($tv['data_length']/1024*100)/100;
$tv['table_free'] = intval($tv['data_free']/1024*100)/100;
$databaseCount+=$tv['table_size'];
}
//单位换算
if(intval($databaseCount) >1024)
{
$databaseCount= intval($databaseCount/1024*100)/100;
$databaseCount=$databaseCount.'MB';
}
else
{
$databaseCount=$databaseCount.'KB';
}
$this->assign("databaseCount",$databaseCount);
$this->assign("tableList",$tableList);
$this->display();
}
步骤一列表页面完毕
————————————我是可爱的分割线———————————
步骤二:编写优化按钮和备份按钮的事件,由于我的事件操作都是ajax完成的。所以需要在前端方面需要一定的了解。
//优化表事件请求方法 这个还是比较简单的
public function optimizeTable()
{
$return=array('code'=>0,'msg'=>'操作失败!','data'=>'');//ajax请求返回参数
$success=array('code'=>200,'msg'=>'操作成功!','data'=>'');
$table= text($_POST['table']);//接收POST过来的表名称
$sql="OPTIMIZE TABLE ".$table;
$result= M()->query($sql);
if($result)
{
exit(json_encode($success));
}
else
{
exit(json_encode($return));
}
}
OPTIMIZE TABLE $table_name 这条sql语句想要深入了解的就需要自行百度下啦,这里就不叙述,以免篇幅过长。
————————————我是可爱的分割线———————————
步骤三:接下来是本文的重点。我的思路是先把单表的备份写好了,我想全部备份应该也没啥问题,所以结果当然也是我想的那样,相当顺利。
//单表备份
public function backupTable()
{
$backup_url='./data/database/';//先定义好数据库文件备份位置
$return=array('code'=>0,'msg'=>'操作失败!','data'=>'');
$success=array('code'=>200,'msg'=>'操作成功!','data'=>'');
$table= text($_POST['table']);
$sql='show create table '.$table;//获取表结构
$tableDesc= M()->query($sql);
//备份表结构 和 表数据
if(!empty($tableDesc[0]['create table']))//判断是否存在表数据结构
{
$backupStr='#ForAcerCms Backup File'."\n\n";//拼接自定义注释语句 \n是写入文件的linux换行符 \r\n 是windows里面的而且换行符一定要放在 "\n"双引号内,单引号是没用的。
$backupStr.='#table : '.$table.' , backup time '.date('Y-m-d H:i:s', time())."\n\n";//拼接自定义注释语句
$backupStr.='DROP TABLE IF EXISTS '.$table.';'."\n";//拼接自定义注释语句
$backupStr.=$tableDesc[0]['create table'].';'."\n\n";//将表结构放入到自定义字符串中
//取表字段 这个很重要
$getTableField='show columns from '.$table;
$tableFieldList= M()->query($getTableField);
$fieldListData= getSubByKey($tableFieldList,'field'); //这个方法是 从一个二维数组中 抽取某一个字段数据成一维数组
$fieldList= implode(',',$fieldListData);//将一维数组使用 , 分隔开其实这步可以不用可以省略
//读取表数据
$getSql="select * from ".$table;
$tableDataList= M()->query($getSql);
//组装数据将 获得的数据 拼装成 insert into $table_name value();的字符串
foreach($tableDataListas$v)
{
$valueStr='';
for($i=0;$i
{
if($i== count($v)-1)
{
$valueStr.="'".$v[$fieldListData[$i]]."'";
}
else
{
$valueStr.="'".$v[$fieldListData[$i]]."'".',';
}
}
$backupStr.='insert into '.$table.' values ('.$valueStr.');'."\n";
}
//写入文件 之后把封装好的 $backupStr 写入到自定义文件中sql中,也可以用作sql导入文件,亲测有效。
$file_name=$table.'_'.date('YmdHis', time()).'.sql';
$file_url=$backup_url.$file_name;
$file= fopen($file_url,"w+");
$result= fwrite($file,$backupStr);
fclose($file);
}
else
{
exit(json_encode($return));
}
if($result)
{
exit(json_encode($success));
}
else
{
exit(json_encode($return));
}
}
单表的完成之后,多表的就简单啦,就是在获取table那个位置增加一层对table的循环。这样就比较费时了,所以在用户操作的时候一定要提示用户在备份中或者禁止用户操作刷新页面,不然备份会被中断而失败。之后这里贴上多表备份的代码,稍稍的有一些不同,代码都是大同小异的。各位看官请看:
//多表备份
public function backupAllTable()
{
$backup_url='./data/database/';
$return=array('code'=>0,'msg'=>'操作失败!','data'=>'');
$success=array('code'=>200,'msg'=>'操作成功!','data'=>'');
$dataName= C("DB_NAME");
$getTableListsql="SHOW TABLE STATUS FROM ".$dataName;//列出数据库所有的表
$tableList= M()->query($getTableListsql);
$backupStr='#ForAcerCms Backup File'."\n\n";
foreach($tableListas$tv)
{
$table=$tv['name'];
$sql='show create table '.$table;
$tableDesc= M()->query($sql);
//备份表结构 和 表数据
if(!empty($tableDesc[0]['create table']))
{
$backupStr.='#table : '.$table.' , backup time '.date('Y-m-d H:i:s', time())."\n\n";
$backupStr.='DROP TABLE IF EXISTS '.$table.';'."\n";
$backupStr.=$tableDesc[0]['create table'].';'."\n\n";
//取表字段
$getTableField='show columns from '.$table;
$tableFieldList= M()->query($getTableField);
$fieldListData= getSubByKey($tableFieldList,'field');
$fieldList= implode(',',$fieldListData);
//读取表数据
$getSql="select * from ".$table;
$tableDataList= M()->query($getSql);
foreach($tableDataList as $key=>$v)
{
$valueStr='';
for($i=0;$i
{
if($i== count($v)-1)
{
$valueStr.="'".$v[$fieldListData[$i]]."'";
}
else
{
$valueStr.="'".$v[$fieldListData[$i]]."'".',';
}
}
if(count($tableDataList)-1==$key)
{
$backupStr.='insert into '.$table.' values ('.$valueStr.');'."\n\n\n";
}
else
{
$backupStr.='insert into '.$table.' values ('.$valueStr.');'."\n";
}
}
}
else
{
exit(json_encode($return));
}
}
//写入文件
$file_name='cms_system_'.date('YmdHis', time()).'.sql';
$file_url=$backup_url.$file_name;
$file= fopen($file_url,"w+");
$result= fwrite($file,$backupStr);
fclose($file);
if($result)
{
exit(json_encode($success));
}
else
{
exit(json_encode($return));
}
}
最后来一张效果图:
————————————我是可爱的分割线———————————
步骤三结束啦,看到这里你看懂了吗?没看懂没事,有疑问可以提出来,互相交流一下,作为一个程序员,讨论问题是最有趣的了,比如说:PHP是世界上最好的编程语言,没有之一(手动滑稽)!
「everything has a price」