关于本站
“最难不过坚持”
本人承接扒站仿站,php网站维护,病毒查杀,网站编辑,网站改版,html制作
有需要网站维护,改版,病毒查杀,网站编辑,网站备案,html制作等相关的工作可以联系我。
本人有多年相关工作经验,也可提供免费咨询,交个朋友。
有需要探讨问题的朋友,也可以加我微信,共同探讨!
微信:15011482830 QQ:408917339
2712
39
分类目录
最新评论
- https://jueru.net/
-
评 留言
- :weixiao:
-
评 留言
- :shuijiao: :weiqu: :zhenbang: :leng:
-
评 留言
- :yiwen: :yiwen: :yiwen: :yiwen:
-
评 EasySass: could not generate CSS file. See Output panel for details.
- 这个业务逻辑多少都有点奇怪了,阅读浏览次数增值在新闻详情页的控制器方法里setInc,这怎么还写进模型事件里了。如果非要用onAfterRead也可以,把新闻文章的内容单独分出来一个news_content表,然后把它和news做关联,然后给news_content表的onAfterRead事件做增值处理,这样点进新闻页内查询到文章内容时才会触发它。
-
评 TP6模型事件-查询后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了,很好,对不对...
评论加载中...
2022-04-07 12:35:23
回复