关于本站
“最难不过坚持”
本人承接扒站仿站,php网站维护,病毒查杀,网站编辑,网站改版,html制作
有需要网站维护,改版,病毒查杀,网站编辑,网站备案,html制作等相关的工作可以联系我。
本人有多年相关工作经验,也可提供免费咨询,交个朋友。
有需要探讨问题的朋友,也可以加我微信,共同探讨!
微信:15011482830 QQ:408917339
2655
39
分类目录
最新评论
- https://jueru.net/
-
- :weixiao:
-
- :shuijiao: :weiqu: :zhenbang: :leng:
-
- :yiwen: :yiwen: :yiwen: :yiwen:
-
- 这个业务逻辑多少都有点奇怪了,阅读浏览次数增值在新闻详情页的控制器方法里setInc,这怎么还写进模型事件里了。如果非要用onAfterRead也可以,把新闻文章的内容单独分出来一个news_content表,然后把它和news做关联,然后给news_content表的onAfterRead事件做增值处理,这样点进新闻页内查询到文章内容时才会触发它。
-
文章标签更多
tp6用tp5er实现数据库备份,数据库还原
composer命令安装:composer require tp5er/tp5-databackup dev-master
安装成功后会在项目文件夹vendor下自动生成数据库备份类库:
安装好之后,里面的test文件夹是案例,但是是tp5的语法,用在tp6上,需要改一下
控制器代码:Database2.php
<?php namespace app\admin\controller; use think\facade\Request; use think\facade\Session; use \tp5er\Backup; class Database2 extends Base{ public function index() { $db= new Backup(); return view('index',['list'=>$db->dataList()]); } //备份文件列表 public function importlist() { $db= new Backup(); return view('importlist',['list'=>$db->fileList()]); } public function import($time = 0, $part = null, $start = null) { $db= new Backup(); if(is_numeric($time) && is_null($part) && is_null($start)){ $list = $db->getFile('timeverif',$time); if(is_array($list)){ session::set('backup_list', $list); return ZHTReturn('初始化完成!', 1, array('part' => 1, 'start' => 0)); }else{ return ZHTReturn('备份文件可能已经损坏,请检查!'); } }else if(is_numeric($part) && is_numeric($start)){ $list=session::get('backup_list'); $start= $db->setFile($list)->import($start,$time); if( false===$start){ return ZHTReturn('还原数据出错!'); }elseif(0 === $start){ if(isset($list[++$part])){ $data = array('part' => $part, 'start' => 0); return ZHTReturn("正在还原...#{$part}", 1, $data); } else { session::delete('backup_list'); return ZHTReturn('还原完成!',1); } }else{ $data = array('part' => $part, 'start' => $start[0]); if($start[1]){ $rate = floor(100 * ($start[0] / $start[1])); return ZHTReturn("正在还原...#{$part} ({$rate}%)", 1, $data); } else { $data['gz'] = 1; return ZHTReturn("正在还原...#{$part}", 1, $data); } return ZHTReturn("正在还原...#{$part}", 1); } }else{ return ZHTReturn('参数错误!'); } } /** * 删除备份文件 */ public function del($time = 0){ $db= new Backup(); if($db->delFile($time)){ return ZHTReturn("备份文件删除成功!",1); }else{ return ZHTReturn("备份文件删除失败,请检查权限!"); } } /** * 下载备份文件 */ public function down($time = 0){ $db= new Backup(); $db->downloadFile($time); } //备份表 public function export() { $db= new Backup(); if(Request::instance()->isPost()){ $input=input('post.'); $fileinfo =$db->getFile(); //检查是否有正在执行的任务 $lock = "{$fileinfo['filepath']}backup.lock"; if(is_file($lock)){ return ZHTReturn('检测到有一个备份任务正在执行,请稍后再试!'); } else { //创建锁文件 file_put_contents($lock,time()); } // 检查备份目录是否可写 if(!is_writeable($fileinfo['filepath'])){ return ZHTReturn('备份目录不存在或不可写,请检查后重试!'); } //缓存锁文件 session::set('lock', $lock); //缓存备份文件信息 session::set('backup_file', $fileinfo['file']); //缓存要备份的表 session::set('backup_tables', $input['tables']); //创建备份文件 if(false !== $db->Backup_Init()){ return ZHTReturn('初始化成功!',1,['tab'=>['id' => 0, 'start' => 0]]); }else{ return ZHTReturn('初始化失败,备份文件创建失败!'); } }else if(Request::instance()->isGet()){ $tables = session::get('backup_tables'); $file=session::get('backup_file'); $id=input('id'); $start=input('start'); $start= $db->setFile($file)->backup($tables[$id], $start); if(false === $start){ return ZHTReturn('备份出错!'); }else if(0 === $start){ if(isset($tables[++$id])){ $tab = array('id' => $id, 'start' => 0); return ZHTReturn('备份完成!', 1, array('tab' => $tab)); } else { //备份完成,清空缓存 unlink(session::get('lock')); Session::delete('backup_tables'); Session::delete('backup_file'); return ZHTReturn('备份完成!',1); } } }else{ return ZHTReturn('参数错误!'); } } //修复表 public function repair($tables= null) { $db= new Backup(); if($db->repair($tables)){ return ZHTReturn("数据表修复完成!",1); }else{ return ZHTReturn("数据表修复出错请重试"); } } //优化表 public function optimize($tables= null) { $db= new Backup(); if($db->optimize($tables)){ return ZHTReturn("数据表优化完成!",1); }else{ return ZHTReturn("数据表优化出错请重试!"); } } }数据库备份页面index.html
<link rel="stylesheet" type="text/css" href="https://www.layuicdn.com/layui/css/layui.css" /> <script src="https://www.layuicdn.com/layui/layui.js"></script> <script> layui.use(['jquery','layer'],function(){ window.$ = layui.$; var layer = layui.layer; //备份表方法 $("#export").click(function(){ $(this).html("正在发送备份请求..."); $.post( $("#export-form").attr("action"), $("#export-form").serialize(), function(data){ if(data.status==1){ $("#export").html( "开始备份,请不要关闭本页面!"); backup(data.data.tab); window.onbeforeunload = function(){ return "正在备份数据库,请不要关闭!" } }else{ layer.tips(data.msg, "#export", { tips: [1, '#3595CC'], time: 4000 }); $("#export").html("立即备份"); } }, "json"); return false; }); //递归备份表 function backup(tab,status){ status && showmsg(tab.id, "开始备份...(0%)"); $.get( $("#export-form").attr("action"), tab, function(data){ // console.log(data) if(data.status==1){ showmsg(tab, data.msg); if(!$.isPlainObject(data.data)){ $("#export").html("备份完成"); window.onbeforeunload = function(){ return null } return; } backup(data.data.tab, tab.id != data.data.tab.id); } else { $("#export").html("立即备份"); } }, "json"); } //修改备份状态 function showmsg(tab, msg){ $("table tbody tr").eq(tab.id).find(".info").html(msg) } //优化表 $("#optimize").click(function(){ $.post(this.href, $("#export-form").serialize(), function(data){ layer.tips(data.msg, "#optimize", { tips: [1, '#3595CC'], time: 4000 }); }, "json"); return false; }); //修复表 $("#repair").on("click",function(e){ $.post(this.href, $("#export-form").serialize(), function(data){ layer.tips(data.msg, "#repair", { tips: [1, '#3595CC'], time: 4000 }); }, "json"); return false; }); }); </script> <div class="layui-form"> <a id="export" class="layui-btn" href="javascript:;" autocomplete="off">立即备份</a> <a id="optimize" href="{:url('database2/optimize')}" class="layui-btn ">优化表</a> <a id="repair" href="{:url('database2/repair')}" class="layui-btn">修复表</a> <a href="{:url('database2/importlist')}" class="layui-btn">还原数据库</a> <form id="export-form" method="post" action="{:url('database2/export')}"> <table class="layui-table"> <thead> <tr> <th width="48"><input class="check-all" checked="checked" type="checkbox" value=""></th> <th>表名</th> <th>数据量</th> <th>数据大小</th> <th>创建时间</th> <th>备份状态</th> <th>操作</th> </tr> </thead> <tbody> {foreach name='list' item='table'} <tr> <td> <input class="ids" type="checkbox" name="tables[]" value="{$table.name}"> </td> <td>{$table.name}</td> <td>{$table.rows}</td> <td>{$table.data_length|ZHTFormatBytes}</td> <td>{$table.create_time}</td> <td class="info">未备份</td> <td> <a href="{:url('database2/optimize',['tables'=>$table['name']])}">优化表</a> <a href="{:url('database2/repair',['tables'=>$table['name']])}">修复表</a> </td> </tr> {/foreach} </tbody> </table> </form> </div>数据库还原页面importlist.html
<link rel="stylesheet" type="text/css" href="https://www.layuicdn.com/layui/css/layui.css" /> <script src="https://www.layuicdn.com/layui/layui.js"></script> <div class="layui-form"> <a class="layui-btn" href="javascript:;" autocomplete="off"> 数据库还原 </a> <table class="layui-table"> <thead> <tr> <th>数据库名称</th> <th>卷数</th> <th>压缩</th> <th>数据大小</th> <th>备份时间</th> <th>状态</th> <th>操作</th> </tr> </thead> <tbody> {foreach name='list' item='data'} <tr> <td>{$data.time|date='Ymd-His'}</td> <td>{$data.part}</td> <td>{$data.compress}</td> <td>{$data.size|ZHTFormatBytes}</td> <td>{$key}</td> <td class="status">-</td> <td class="action"> <a class="db-down" href="{:url('database2/down',['time'=>$data['time']])}">下载</a> <a class="db-import" href="{:url('database2/import',['time'=>$data['time']])}">还原</a> <a class="ajax-get confirm" href="{:url('database2/del',['time'=>$data['time']])}">删除</a> </td> </tr> {/foreach} </tbody> <script> layui.use(['jquery','layer'],function(){ window.$ = layui.$; var layer = layui.layer; $(".db-import").click(function(){ var self = this, status = "."; $(this).parent().prevAll('.status').html("").html('等待还原'); $.get(self.href, success, "json"); window.onbeforeunload = function(){ return "正在还原数据库,请不要关闭!" } return false; function success(data){ if(data.status==1){ console.log(data.msg); $(self).parent().prev().text(data.msg); if($.isPlainObject(data.data)){ $.get(self.href, {"part" : data.data.part, "start" : data.data.start}, success, "json" ); } else { layer.alert(data.msg); //window.onbeforeunload = function(){ return null; } } } else { layer.alert(data.msg); } } }); // $(".db-import").click(function(){ // // console.log($(this).parents().find(".status").html() );//正常 // // console.log($(this).parent().prevAll('.status').html() ); // var statusem=$(this).parent().prevAll('.status'); // $(this).parent().prevAll('.status').html("").html('等待还原'); // thisobj=this; // $.post(this.href, function(data){ // if(data.code==1){ // // statusem.text(""); // 清空数据 // // statusem.append('data'); // // statusem.text("").append('132'); // // $(this).parent().prevAll('.status').html("").html(data.msg);//error :异常原因无法获取当前节点 // statusem.html(data.msg); // getdbimport(thisobj,data.data); // } // }, "json"); // return false; // }); }); </script> </table> </div>
注意:
有一个问题,如果数据库字段值为null,导出时候就变成了空值'',然后,再还原的话,字段值就变成了0,
如果这个字段是delete_time软删除的话,数据表中所有记录就检索不到了。所以需要改一下,加一个判断,如果字段值为null,则导出的也是null
代码:\vendor\tp5er\tp5-databackup\src\Backup.php 333行
foreach ($result as $row) { $arrValues = array(); foreach($row as $key=>$val){ if(is_numeric($val)){ $arrValues[]=$val; }else if(is_null($val)){ $arrValues[]='NULL'; }else{ $arrValues[]="'".str_replace(array("\r", "\n"), array('\\r', '\\n'), addslashes($val))."'"; } } $sql = "INSERT INTO `{$table}` VALUES (" . implode(", ", $arrValues) . ");\n"; if (false === $this->write($sql)) { return false; } }截图:
赏
相关推荐
tp6控制器不存在的解决方法:控制器不存在:app\controller\Index
当我们下载tp6,应用 多应用模式的时候,提示错误:控制器不存在:app\controller\Index,如图:
原因
多应用没有配置
解决方法
步骤如下:
(1)需要安装多应用模式扩展think-multi-app
进入项目根目录。我的路径是(切记改为自己的项目路径):D:\phpStudy\PHPTutorial\...
TP6模型事件-查询后onAfterRead不好用
TP6模型事件-查询后onAfterRead不好用
比如,我想实现浏览新闻后,浏览次数加1
实现:
public static function onAfterRead($news)
{
$news->read_number += 1;
$news->save();
}
运行后,浏览次数加1了,很好,对不对...
评论加载中...