首页> 实战笔录 >PHP开发笔记 >ThinkPHP ThinkPHP

TP6 databackup拓展插件,实现数据库备份下载还原代码分享

作者:小萝卜 2022-10-25 浏览 558

简介TP5 databackup拓展插件,实现数据库备份下载还原代码分享,这里还是使用的T5的databackup拓展插件,改了路由和返回的方式

tp6去实现数据库备份,现在网上没有tp6的方法(有的话请分享给我),直接把T5的扩展扩展拿过来用,改了路由和返回方式是可以使用的。下面操作一下

 

安装扩展

composer require tp5er/tp5-databackup dev-master

控制器部分

<?php
namespace app\admin\controller;
use think\Db;
use think\Request;
use think\facade\Session;
use \tp5er\Backup;
use think\facade\View;
class Databackup extends IsLogin
{
    public function index()
    {
      $db= new Backup();
      return View::fetch('index',['list'=>$db->dataList()]);
    }
   //备份文件列表
   public function importlist()
   {
        $db= new Backup();
       return View::fetch('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);
               //$this->success('初始化完成!', '', array('part' => 1, 'start' => 0));
               return json(['code'=>1,'msg'=>"初始化完成!",'data'=>array('part' => 1, 'start' => 0)]);
           }else{
               //$this->error('备份文件可能已经损坏,请检查!');
               return json(['code'=>0,'msg'=>"备份文件可能已经损坏,请检查!"]);
           }
       }else if(is_numeric($part) && is_numeric($start)){

               $list=Session::get('backup_list');
               
               $start= $db->setFile($list)->import($start,$time);
              
               if( false===$start){
                     //$this->error('还原数据出错!');
                     return json(['code'=>0,'msg'=>"还原数据出错!"]);
               }elseif(0 === $start){
                   if(isset($list[++$part])){
                       $data = array('part' => $part, 'start' => 0);
                       //$this->success("正在还原...#{$part}", '', $data);
                       return json(['code'=>1,'msg'=>"正在还原...#{$part}",'data'=>$data]);
                   } else {
                       Session::delete('backup_list');
                       //$this->success('还原完成!');
                       return json(['code'=>1,'msg'=>"还原完成!"]);
                   }
               }else{
                   $data = array('part' => $part, 'start' => $start[0]);
                   if($start[1]){
                       $rate = floor(100 * ($start[0] / $start[1]));
                       //$this->success("正在还原...#{$part} ({$rate}%)", '', $data);
                       return json(['code'=>1,'msg'=>"正在还原...#{$part}",'data'=>$data]);

                   } else {
                       $data['gz'] = 1;
                       //$this->success("正在还原...#{$part}", '', $data);
                       return json(['code'=>1,'msg'=>"正在还原...#{$part}"]);
                   }
                   $this->success("正在还原...#{$part}", '');
                   
               }
           
           
       }else{
           //$this->error('参数错误!');
           return json(['code'=>0,'msg'=>"参数错误!"]);
       }

      
   }
   /**
    * 删除备份文件
    */
   public function del($time = 0){
       $db= new Backup();
       if($db->delFile($time)){
           return json(['code'=>1,'msg'=>"备份文件删除成功!"]);
       }else{
           return json(['code'=>0,'msg'=>"备份文件删除失败,请检查权限!"]);
       }
   }
    /**
    * 下载备份文件
    */
   public function down($time = 0){
       $db= new Backup();
       $db->downloadFile($time);
   }

    //备份表
    public function export()
    {

        $db  = new Backup();
        if(Request()->isPost()){
            $input      =  input('post.');

            if(empty($input['tables'])){
                return json(['code'=>0,'msg'=>"请选择要备份的数据表!"]);
            }
          
            $fileinfo   =  $db->getFile();
            //检查是否有正在执行的任务
            $lock       =  "{$fileinfo['filepath']}backup.lock";
            if(is_file($lock)){
                return json(['code'=>0,'msg'=>"检测到有一个备份任务正在执行,请稍后再试"]);
            } else {
                //创建锁文件
                file_put_contents($lock,time());
            }
            // 检查备份目录是否可写
            if(!is_writeable($fileinfo['filepath']))  return json(['code'=>0,'msg'=>"备份目录不存在或不可写,请检查后重试!"]);

            //缓存锁文件
            Session::set('lock', $lock);
            //缓存备份文件信息
            Session::set('backup_file', $fileinfo['file']);
            //缓存要备份的表
            Session::set('backup_tables', $input['tables']);
            //创建备份文件
            if(false !== $db->Backup_Init()){
                return json(['code'=>1,'msg'=>"初始化成功!",'data'=>['tab'=>['id' => 0, 'start' => 0]]]);
            }else{
                return json(['code'=>0,'msg'=>"初始化失败,备份文件创建失败!"]);
            }
        }else if(Request()->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 json(['code'=>0,'msg'=>"备份出错!"]);
            }else if(0 === $start){
                if(isset($tables[++$id])){
                    $tab = array('id' => $id, 'start' => 0);
                    return json(['code'=>1,'msg'=>"备份完成!",'data'=>array('tab' => $tab)]);
                } else { //备份完成,清空缓存
                    unlink(Session::get('lock'));
                    Session::delete('backup_tables');
                    Session::delete('backup_file');
                    return json(['code'=>1,'msg'=>"备份完成!"]);
                }
            }else {
                $tab  = array('id' => $id, 'start' => $start[0]);
                $rate = floor(100 * ($start[0] / $start[1]));
                return json(['code'=>1,'msg'=>"正在备份...({$rate}%)",'data'=>array('tab' => $tab)]);
            }
        }else{
            return json(['code'=>0,'msg'=>"参数错误!"]);
        }


    }

    //修复表
    public function repair($tables= null)
    {
        $db= new Backup();
        if(empty($tables)) return json(['code'=>0,'msg'=>"请选择要优化的表"]);

        if($db->repair($tables)){
            return json(['code'=>1,'msg'=>"数据表修复完成!"]);
        }else{
            return json(['code'=>0,'msg'=>"数据表修复出错请重试"]);
        }
    }
    //优化表
    public function optimize($tables= null)
    {
        $db= new Backup();
        if(empty($tables)) return json(['code'=>0,'msg'=>"请选择要修复的表"]);
        if($db->optimize($tables)){
            return json(['code'=>1,'msg'=>"数据表优化完成!"]);
        }else{
            return json(['code'=>0,'msg'=>"数据表优化出错请重试!"]);
        }
    }



}

备份html:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<link rel="stylesheet" type="text/css" href="__PUBLIC__/admin/layui/css/layui.css" media="all">
    <script type="text/javascript" src="__PUBLIC__/admin/layui/layui.js"></script>
</head>
<body>
<br>
	<script>
    layui.use(['jquery','layer','form'],function(){
      window.$ = layui.$;
      var layer = layui.layer;
      var form = layui.form; 
      var $ = layui.jquery;
      //备份表方法
      $("#export").click(function(){
          $(this).html("正在发送备份请求...");
          $.post(
            $("#export-form").attr("action"),
            $("#export-form").serialize(), 
            function(data){
               
              if(data.code==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.code==1){
                  showmsg(tab, data.msg);

                  if(!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);
       //console.log(msg);

    }
   
     //优化表
      $("#optimize").click(function(){
      	   $('#optimize').html('正在优化...');
           $.post(this.href, $("#export-form").serialize(), function(data){
           
              // layer.tips(data.msg, "#optimize", {
              //   tips: [1, '#3595CC'],
              //   time: 4000
              // });
              layer.alert(data.msg);
              $('#optimize').html('优化表');
    
            }, "json");
            return false;    
      });

      //修复表
      $("#repair").on("click",function(e){
          $('#repair').html('正在修复...');
          $.post(this.href, $("#export-form").serialize(), function(data){
            // layer.tips(data.msg, "#repair", {
            //   tips: [1, '#3595CC'],
            //   time: 4000
            // });
            layer.alert(data.msg);
            $('#repair').html('修复表');
            }, "json");
            return false; 
      });
      
      //优化表—-单
      $(".optimize").click(function(){
      	   var _this=$(this);
      	   _this.html('正在优化...');
           $.post(this.href, {}, function(data){
           
            layer.alert(data.msg);
            _this.html('优化表');
    
            }, "json");
            return false;    
      });

      //修复表-单
      $(".repair").on("click",function(e){
      	  var _this=$(this);
          _this.html('正在修复...');
          $.post(this.href, {}, function(data){
	            layer.alert(data.msg);
	            _this.html('修复表');
            }, "json");
            return false; 
      });

      /***
      * layui 复选框全选/反选
      * author:Abner
      * qq:346882795
      * date: 2019.11.06 9:45
      *
      **/
      form.on('checkbox(allcheckbox)', function (data) {
          var isbool = $(this).is(':checked') ? true : false ;
          console.log(isbool);
           $("input[name='tables[]']").each(function(){ 
              $(this).prop("checked",  isbool );
            })

           form.render(); 
 
        });


    });

  </script>


<div  style="padding:20px;">
    <a id="export" class="layui-btn" href="javascript:;" autocomplete="off">立即备份</a>

    <a id="optimize" href="{?:url('/Databackup/optimize')?}" class="layui-btn ">优化表</a>
    <a id="repair" href="{?:url('/Databackup/repair')?}" class="layui-btn">修复表</a>
    <a  href="{?:url('/Databackup/importlist')?}" class="layui-btn">还原数据库</a>
    <form class="layui-form" id="export-form" method="post" action="{?:url('/Databackup/export')?}">
    <table class="layui-table">


      <thead>
        <tr>
            <th width="48"><input class="check-all" checked="chedked" type="checkbox" value="" lay-filter="allcheckbox" lay-skin="primary"></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" checked="chedked" type="checkbox" name="tables[]" value="{?$table.name?}" lay-skin="primary">
          </td>
          <td>{?$table.name?}</td>
          <td>{?$table.rows?}</td>
          <td>{?$table.data_length|format_bytes?}</td>
          <td>{?$table.create_time?}</td>
          <td class="info">未备份</td>
          <td>
              <a  href="{?:url('/Databackup/optimize',['tables'=>$table['name']])?}" class="optimize">优化表</a>&nbsp;
              <a  href="{?:url('/Databackup/repair',['tables'=>$table['name']])?}" class="repair">修复表</a>
              <!-- <a  href="{?:url('optimize',['tables'=>$table['name']])?}" class="optimize">优化表</a>&nbsp;
              <a  href="{?:url('repair',['tables'=>$table['name']])?}" class="repair">修复表</a> -->
          </td>
        </tr>
    {?/foreach?}
      </tbody>


    </table>
  </form>
  </div>
</body>
</html>

还原html:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<link rel="stylesheet" type="text/css" href="__PUBLIC__/admin/layui/css/layui.css" media="all">
    <script type="text/javascript" src="__PUBLIC__/admin/layui/layui.js"></script>
</head>
<body>
<br>
<div class="layui-form" style="padding:20px;">
   
    <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|format_bytes?}</td>
          <td>{?$key?}</td>
          <td class="status">-</td>
          <td class="action">
              <a class="db-down" href="{?:url('/Databackup/down',['time'=>$data['time']])?}">下载</a>&nbsp;
              <!-- <a class="db-import" href="{?:url('/Databackup/import',['time'=>$data['time']])?}">还原</a>&nbsp; -->
              <a class="ajax-get confirm" href="{?:url('/Databackup/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.code==1){

                    $(self).parent().prev().text(data.msg);

                    if(data.data.part){
                        $.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);
                }
            }
        });

      $('.ajax-get').click(function(){
            var self    = $(this);
            var selfUrl = this.href;
             layer.confirm('删除后将无法恢复,请谨慎操作', {
             btn: ['删除','取消'] ,
             skin: 'layui-layer-lan'   //主题皮肤 可选 参考官网
             },function(index){   //确定回掉
                 layer.close(index);
                 alert(selfUrl);
                    $.post(selfUrl,{},function(data){
                      layer.alert(data.msg);
                      self.parent().parent().remove(); 
                    });
             },function(index){
              layer.close(index);
             });


      	    return false; 
      });

});

</script>

    </table>

</div>
</body>
</html>


还原的时候貌似有点问题,所以隐藏掉了。希望大神能指出还原是哪里出问题了。。我这一直报错

很赞哦! (0)

文章评论

    高端网站建设