public static function export($dir=‘data’) {
//保存路径,默认为站点根目录下的data文件夹里
p a t h = R O O T P A T H . path = ROOT_PATH . path=ROOTPATH.dir.DIRECTORY_SEPARATOR;
//获取数据库名
$dbname=config(“database.database”);
//检查目录是否存在
if(!is_dir($path)) {
//新建目录
mkdir($path, 0777, true);
}
//检查目录是否可写
if(!is_writable($path)) {
chmod($path,0777);
}
//检查文件是否存在
f i l e N a m e = fileName= fileName=dbname.’_’.date(“Y-m-d”,time()).’.sql’;
//数据库保存相对路径
$filePath = d i r . D I R E C T O R Y S E P A R A T O R . dir.DIRECTORY_SEPARATOR. dir.DIRECTORYSEPARATOR.fileName;
//硬盘保存绝对路径
$savepath = p a t h . path. path.fileName;
try{
if(!file_exists($savepath)) {
//获取mysql版本
$version = Db::query(“select version() as ver”);
$ver = $version[0][‘ver’];
$info = “-- ----------------------------\r\n”;
$info .= “-- 日期:”.date(“Y-m-d H:i:s”,time())."\r\n";
i n f o . = " − − M y S Q L − " . info .= "-- MySQL - ". info.="−−MySQL−".ver." : Database - “.$dbname.”\r\n";
$info .= “-- ----------------------------\r\n\r\n”;
i n f o . = " C R E A T E D A T A b a s e I F N O T E X I S T S ‘ " . info .= "CREATE DATAbase IF NOT EXISTS `". info.="CREATEDATAbaseIFNOTEXISTS‘".dbname."` DEFAULT CHARACTER SET utf8 ;\r\n\r\n";
i n f o . = " U S E ‘ " . info .= "USE `". info.="USE‘".dbname."`;\r\n\r\n";
file_put_contents( s a v e p a t h , savepath, savepath,info,FILE_APPEND);
//查询所有表
$sql=“show tables”;
//执行原生SQL语句
r e s u l t = D b : : q u e r y ( result=Db::query( result=Db::query(sql);
foreach ($result as k = > k=> k=>v) {
//查询表结构
$table = KaTeX parse error: Expected group after '_' at position 13: v['Tables_in_̲'.dbname];
s q l t a b l e = " s h o w c r e a t e t a b l e " . sql_table = "show create table ". sqltable="showcreatetable".table;
r e s = D b : : q u e r y ( res = Db::query( res=Db::query(sql_table);
$info_table = “-- ----------------------------\r\n”;
i n f o t a b l e . = " − − T a b l e s t r u c t u r e f o r ‘ " . info_table .= "-- Table structure for `". infotable.="−−Tablestructurefor‘".table."`\r\n";
$info_table .= “-- ----------------------------\r\n\r\n”;
i n f o t a b l e . = " D R O P T A B L E I F E X I S T S ‘ " . info_table .= "DROP TABLE IF EXISTS `". infotable.="DROPTABLEIFEXISTS‘".table."`;\r\n\r\n";
$info_table .= $res[0][‘Create Table’].";\r\n\r\n";
//查询表数据
$info_table .= “-- ----------------------------\r\n”;
i n f o t a b l e . = " − − D a t a f o r t h e t a b l e ‘ " . info_table .= "-- Data for the table `". infotable.="−−Dataforthetable‘".table."`\r\n";
$info_table .= “-- ----------------------------\r\n\r\n”;
file_put_contents( s a v e p a t h , savepath, savepath,info_table,FILE_APPEND);
s q l d a t a = " s e l e c t ∗ f r o m " . sql_data = "select * from ". sqldata="select∗from".table;
d a t a = D b : : q u e r y ( data = Db::query( data=Db::query(sql_data);
c o u n t = c o u n t ( count= count( count=count(data);
if($count<1) continue;
foreach ($data as $key => $value) {
KaTeX parse error: Expected '}', got 'EOF' at end of input: …"INSERT INTO `{table}` VALUES (";
foreach($value as $column) {
//对单引号和换行符进行一下转义
KaTeX parse error: Can't use function '\r' in math mode at position 34: …ce( array("'","\̲r̲\n"), array("\'…column);
//当值为空时,使用default默认
s q l S t r . = e m p t y ( sqlStr .=empty( sqlStr.=empty(column) ? “default, " : “’”.$column.”’, ";
}
//去掉最后一个逗号和空格
s q l S t r = s u b s t r ( sqlStr = substr( sqlStr=substr(sqlStr,0,strlen($sqlStr)-2);
$sqlStr .= “);\r\n”;
//KaTeX parse error: Expected '}', got 'EOF' at end of input: …"INSERT INTO `{table}` VALUES (’" . str_replace(array("\r", “\n”), array(’\r’, ‘\n’), implode("’, ‘", $value)) . "’);\n";
file_put_contents( s a v e p a t h , savepath, savepath,sqlStr,FILE_APPEND);
}
$info = “\r\n”;
file_put_contents( s a v e p a t h , savepath, savepath,info,FILE_APPEND);
}
//计算文件大小
s i z e = f i l e s i z e ( size=filesize( size=filesize(savepath);
return array(‘code’ => 1, ‘msg’ => ‘数据库备份成功’,‘name’=> f i l e N a m e , ′ s i z e ′ = > fileName,'size'=> fileName,′size′=>size,‘path’=>$filePath);
}else{
return array(‘code’ => 0, ‘msg’ => ‘备份文件已存在’);
}
} catch (\Exception $e) {
return array(‘code’ => 0, ‘msg’ => ‘备份数据库失败,Error:’.$e);
}
}
/**
-
将sql文件导入到数据库
-
@param string $sqlfile sql文件
*/
public static function import($sqlfile) {
if(!file_exists($sqlfile)) {
return array(‘code’ => 0, ‘msg’ => ‘备份文件不存在’);
}
try {
// 创建保存sqlsql语句的数组
$sqls = array ();
f i l e = f o p e n ( file = fopen ( file=fopen(sqlfile, “rb” );
// 创建表缓冲变量
$table_buffer = ‘’;
while ( ! feof ($file) ) {
// 读取每一行sql
$row = fgets ( $file);
// 如果结尾没有包含’;’(即为一个完整的sql语句,这里是插入语句),并且不包含’ENGINE=’(即创建表的最后一句)
if (! preg_match ( ‘/;/’, $row ) || preg_match ( ‘/ENGINE=/’, $row )) {
// 将本次sql语句与创建表sql连接存起来
$table_buffer .= $row;
// 如果包含了创建表的最后一句
if (preg_match ( ‘/ENGINE=/’, $table_buffer)) {
//执行sql语句创建表
Db::execute($table_buffer);
// 清空当前,准备下一个表的创建
$table_buffer = ‘’;
}
// 跳过本次
continue;
}
//执行sql语句
Db::execute($row);
}
fclose ($file);
return array(‘code’ => 1, ‘msg’ => ‘还原数据库成功’);
}
catch (\Exception $e) {
return array(‘code’ => 0, ‘msg’ => ‘还原数据库失败,Error:’.$e);
}
}
}
二、创建一张数据库表,用于保存备份内容
– Table structure for database
DROP TABLE IF EXISTS database
;
CREATE TABLE database
(
id
int(11) NOT NULL AUTO_INCREMENT,
name
varchar(100) DEFAULT NULL,
size
varchar(20) DEFAULT ‘0’,
path
varchar(255) DEFAULT NULL,
create_time
int(11) DEFAULT NULL,
update_time
int(11) DEFAULT NULL,
delete_time
int(11) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
三、备份数据库
thinkphp后端控制器代码
<?php namespace app\admin\controller; use think\Controller; use think\Db; use app\common\Backup; /** ** @name='备份' */ public function backup() { if(request()->isPost()){ $res=Backup::export(); if($res['code']==1){ //写入数据库 DatabaseModel::create([ 'name' => $res['name'], 'size' => $res['size'], 'path' => $res['path'] ]); $this->success($res['msg']); }else{ $this->error($res['msg']); } } } ### 四、下载备份文件 1、下载数据库备份文件,需要先将.sql文件压缩成zip,因此建议前端配合使用jszip插件,jszip教程参数这篇文章:[https://blog.csdn.net/qq15577969/article/details/115549729]( ) > **Ps**:有的朋友可能会说,直接使用php自带的zip压缩功能不就可以了吗,何必那么麻烦。这个当然也可以,但前提是你使用的php版本安装了php\_zip.dll扩展,然后才能使用ZipArchive类实现zip压缩功能。博主使用的php5.6版本是没有这个扩展的,而且博主开发的系统是要授权给用户使用的,用户不一定都懂安装php扩展,所以为了保险起见,直接选择了配合前端jszip插件来实现压缩的方案。 2、前端js代码: