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

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

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

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

安装拓展:
composer require tp5er/tp5-databackup dev-master

控制器代码:
 
<?php
namespace Admin\admin\controller;
use think\Controller;
use think\Db;
use think\Request;
use think\Session;
use \tp5er\Backup;
use Admin\admin\controller\IsLogins;
/**
 * 数据库备份还原控制器
 */
class Databak extends Islogins{

    public function index()
    {
      $db= new Backup();
      return $this->fetch('index',['list'=>$db->dataList()]);
    }
   //备份文件列表
   public function importlist()
   {
        $db= new Backup();
       return $this->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));
           }else{
               $this->error('备份文件可能已经损坏,请检查!');
           }
       }else if(is_numeric($part) && is_numeric($start)){

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

      
   }
   /**
    * 删除备份文件
    */
   public function del($time = 0){
       $db= new Backup();
       if($db->delFile($time)){
           $this->success("备份文件删除成功!");
       }else{
           $this->error("备份文件删除失败,请检查权限!");
       }
   }
    /**
    * 下载备份文件
    */
   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)){
               $this->error('检测到有一个备份任务正在执行,请稍后再试!');
           } else {
               //创建锁文件
               file_put_contents($lock,time());
           }
           // 检查备份目录是否可写
           is_writeable($fileinfo['filepath']) || $this->error('备份目录不存在或不可写,请检查后重试!');

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


   }

   //修复表
   public function repair($tables= null)
   {
       $db= new Backup();
       if($db->repair($tables)){
           $this->success("数据表修复完成!");
       }else{
           $this->error("数据表修复出错请重试");
       }
   }
   //优化表
   public function optimize($tables= null)
   {
        $db= new Backup();
         if($db->optimize($tables)){
           $this->success("数据表优化完成!");
         }else{
           $this->error("数据表优化出错请重试!");
         }
   }
}

备份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'],function(){
      window.$ = layui.$;
      var layer = layui.layer;
      //备份表方法
      $("#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(!$.isPlainObject(data.data.tab)){
                    $("#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
            });
            $('#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
            });
            $('#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; 
      });


    });

  </script>

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

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


      <thead>
        <tr>
            <th width="48"><input class="check-all" checked="chedked" 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" checked="chedked" type="checkbox" name="tables[]" value="{?$table.name?}" style="display:inline;">
          </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('optimize',['tables'=>$table['name']])?}" class="optimize">优化表</a>&nbsp;
              <a  href="{?:url('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">
   
    <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('down',['time'=>$data['time']])?}">下载</a>&nbsp;
              <a class="db-import" href="{?:url('import',['time'=>$data['time']])?}">还原</a>&nbsp;
              <a class="ajax-get confirm" href="{?:url('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);
            $.post(this.href,{},function(data){
            	 layer.alert(data.msg);
            	 self.parent().parent().remove(); 
            });

      	    return false; 
      });

});

</script>

    </table>

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

很赞哦! (0)

文章评论

    高端网站建设