您现在的位置是:首页 PHP

thinkphp3.2.3数据库还原备份分享

博主 添加时间:2016-12-03 12:20:48 【PHP】 热度:1223人已围观

1 数据库备份类  详情如下:下载类 MySQLReback.class.php.zip 

<?php
namespace OrgNet;
class MySQLReback {
    

    private $config;
    private $content;
    private $dbName = array();

    const DIR_SEP = DIRECTORY_SEPARATOR;

    public function __construct($config) {
        $this->config = $config;
        header("Content-type: text/html;charset=utf-8");
        $this->connect();
    }

    private function connect() {
        if (mysql_connect($this->config['host'] . ':' . $this->config['port'], $this->config['userName'], $this->config['userPassword'])) {
            mysql_query("SET NAMES '{$this->config['charset']}'");
            mysql_query("set interactive_timeout=24*3600");
        } else {
            $this->throwException('无法连接到数据库!');
        }
    }

    public function setDBName($dbName = '*') {
        if ($dbName == '*') {
            $rs = mysql_list_dbs();
            $rows = mysql_num_rows($rs);
            if ($rows) {
                for ($i = 0; $i < $rows; $i++) {
                    $dbName = mysql_tablename($rs, $i);
                    $block = array('information_schema', 'mysql');
                    if (!in_array($dbName, $block)) {
                        $this->dbName[] = $dbName;
                    }
                }
            } else {
                $this->throwException('没有任何数据库!');
            }
        } else {
            $this->dbName = func_get_args();
        }
    }

    private function getFile($fileName) {
        $this->content = '';
        $fileName = $this->trimPath($this->config['path'] . self::DIR_SEP . $fileName);
        if (is_file($fileName)) {
            $ext = strrchr($fileName, '.');
            if ($ext == '.sql') {
                $this->content = file_get_contents($fileName);
            } elseif ($ext == '.gz') {
                $this->content = implode('', gzfile($fileName));
            } else {
                $this->throwException('无法识别的文件格式!');
            }
        } else {
            $this->throwException('文件不存在!');
        }
    }

    private function setFile() {
        $recognize = '';
        $recognize = implode('_', $this->dbName);
        $fileName = $this->trimPath($this->config['path'] . self::DIR_SEP . $recognize . '_' . date('YmdHis') . '_' . mt_rand(100000000, 999999999) . '.sql');
        $path = $this->setPath($fileName);
        if ($path !== true) {
            $this->throwException("无法创建备份目录目录 '$path'");
        }
        if ($this->config['isCompress'] == 0) {
            if (!file_put_contents($fileName, $this->content, LOCK_EX)) {
                $this->throwException('写入文件失败,请检查磁盘空间或者权限!');
            }
        } else {
            if (function_exists('gzwrite')) {
                $fileName .= '.gz';
                if ($gz = gzopen($fileName, 'wb')) {
                    gzwrite($gz, $this->content);
                    gzclose($gz);
                } else {
                    $this->throwException('写入文件失败,请检查磁盘空间或者权限!');
                }
            } else {
                $this->throwException('没有开启gzip扩展!');
            }
        }
        if ($this->config['isDownload']) {
            $this->downloadFile($fileName);
        }
    }

    private function trimPath($path) {
        return str_replace(array('/', '', '//', ''), self::DIR_SEP, $path);
    }

    private function setPath($fileName) {
        $dirs = explode(self::DIR_SEP, dirname($fileName));
        $tmp = '';
        foreach ($dirs as $dir) {
            $tmp .= $dir . self::DIR_SEP;
            if (!file_exists($tmp) && !@mkdir($tmp, 0777))
                return $tmp;
        }
        return true;
    }

    private function downloadFile($fileName) {
        ob_end_clean();
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Length: ' . filesize($fileName));
        header('Content-Disposition: attachment; filename=' . basename($fileName));
        readfile($fileName);
    }

    private function backquote($str) {
        return "`{$str}`";
    }

    private function getTables($dbName) {
        @$rs = mysql_list_tables($dbName);
        $rows = mysql_num_rows($rs);
        $dbprefix = $this->config['dbprefix'];
        for ($i = 0; $i < $rows; $i++) {
            $tbName = mysql_tablename($rs, $i);
            if (substr($tbName, 0, strlen($dbprefix)) == $dbprefix) {
                $tables[] = $tbName;
            }
        }
        return $tables;
    }

    private function chunkArrayByByte($array, $byte = 5120) {
        $i = 0;
        $sum = 0;
        foreach ($array as $v) {
            $sum += strlen($v);
            if ($sum < $byte) {
                $return[$i][] = $v;
            } elseif ($sum == $byte) {
                $return[++$i][] = $v;
                $sum = 0;
            } else {
                $return[++$i][] = $v;
                $i++;
                $sum = 0;
            }
        }
        return $return;
    }

    public function backup() {
        $this->content = '/* This file is created by MySQLReback ' . date('Y-m-d H:i:s') . ' */';
        foreach ($this->dbName as $dbName) {
            $qDbName = $this->backquote($dbName);
            $rs = mysql_query("SHOW CREATE DATABASE {$qDbName}");
            if ($row = mysql_fetch_row($rs)) {
                mysql_select_db($dbName);
                $tables = $this->getTables($dbName);
                foreach ($tables as $table) {
                    $table = $this->backquote($table);
                    $tableRs = mysql_query("SHOW CREATE TABLE {$table}");
                    if ($tableRow = mysql_fetch_row($tableRs)) {
                        $this->content .= "rn /* 创建表结构 {$table} */";
                        $this->content .= "rn DROP TABLE IF EXISTS {$table};/* MySQLReback Separation */ {$tableRow[1]};/* MySQLReback Separation */";
                        $tableDateRs = mysql_query("SELECT * FROM {$table}");
                        $valuesArr = array();
                        $values = '';
                        while ($tableDateRow = mysql_fetch_row($tableDateRs)) {
                            foreach ($tableDateRow as &$v) {
                                $v = "'" . addslashes($v) . "'";
                            }
                            $valuesArr[] = '(' . implode(',', $tableDateRow) . ')';
                        }
                        $temp = $this->chunkArrayByByte($valuesArr);
                        if (is_array($temp)) {
                            foreach ($temp as $v) {
                                $values = implode(',', $v) . ';/* MySQLReback Separation */';
                                if ($values != ';/* MySQLReback Separation */') {
                                    $this->content .= "rn /* 插入数据 {$table} */";
                                    $this->content .= "rn INSERT INTO {$table} VALUES {$values}";
                                }
                            }
                        }
                    }
                }
            } else {
                $this->throwException('未能找到数据库!');
            }
        }
        if (!empty($this->content)) {
            $this->setFile();
        }
        return true;
    }

    public function recover($fileName) {
        $this->getFile($fileName);
        if (!empty($this->content)) {
            $content = explode(';/* MySQLReback Separation */', $this->content);
            foreach ($content as $i => $sql) {
                $sql = trim($sql);

                if (!empty($sql)) {
                    $dbName = $this->dbName[0];
                    
                    if (!mysql_select_db($dbName))$this->throwException('不存在的数据库!' . mysql_error());
                    $rs = mysql_query($sql);
                    if ($rs) {
                        if (strstr($sql, 'CREATE DATABASE')) {
                            $dbNameArr = sscanf($sql, 'CREATE DATABASE %s');
                            $dbName = trim($dbNameArr[0], '`');
                            mysql_select_db($dbName);
                        }
                    } else {
                        $this->throwException('备份文件被损坏!' . mysql_error());
                    }
                }
            }
        } else {
            $this->throwException('无法读取备份文件!');
        }
        return true;
    }

    private function throwException($error) {
      return $error;
    }

}

?>

2 php端 加载 引入 数据库类 下载 BakController.class.php.zip 详情如下

<?php
namespace ManagerController;
use ThinkController;
class BakController extends BokeController {

    public function index(){
        $DataDir = "sqldatabak/";
        // 创建目录
        mkdir($DataDir); 
        if (!empty($_GET['Action'])) 
        {
            // 加班数据配置信息
            $config = array(
                'host' => C('DB_HOST'),
                'port' => C('DB_PORT'),
                'userName' => C('DB_USER'),
                'userPassword' => C('DB_PWD'),
                'dbprefix' => C('DB_PREFIX'),
                'charset' => 'UTF8',
                'path' => $DataDir,
                'isCompress' => 0, //是否开启gzip压缩
                'isDownload' => 0
            );
            // 加载Mysql类
            $mr = new OrgNetMySQLReback($config);
            $mr->setDBName(C('DB_NAME'));
            if ($_GET['Action'] == 'backup') 
            {
                $mr->backup();
                // echo "<script>document.location.href='" . U("Bak/index") . "'</script>";
                // $this->success( '数据库备份成功!');
            }elseif($_GET['Action'] == 'RL') 
            {
                $mr->recover($_GET['File'].'.sql');
                // echo "<script>document.location.href='" . U("Bak/index") . "'</script>";
                $this->success( '数据库还原成功!');exit();
            }elseif($_GET['Action'] == 'Del') 
            {
                if (@unlink($DataDir . $_GET['File'].'.sql')) 
                {
                    // $this->success('删除成功!');
                    // echo "<script>document.location.href='" . U("Bak/index") . "'</script>";
                } else {
                    $this->error('删除失败!');
                }
            }

            if ($_GET['Action'] == 'download') {
                $this->DownloadFile($DataDir . $_GET['file'].'.sql');
                exit();
            }
        }

        $lists = $this->MyScandir('sqldatabak/');
        $this->datadir = $DataDir;
        $this->lists =  $lists;
        $this->display();
    }



    /***
     *  desc    读取sql数据
     *  Author  lizongyang
     *  web     www.lizongyang.cn
     *  email    1638500136
     ***/
    Public function MyScandir($FilePath = './', $Order = 0){
        $FilePath = opendir($FilePath);
        while (false !== ($filename = readdir($FilePath)))
        {
            $FileAndFolderAyy[] = $filename;
        }
        $Order == 0 ? sort($FileAndFolderAyy) : rsort($FileAndFolderAyy);
        return $FileAndFolderAyy;
    }

   
    /***
     *  desc    下载
     *  Author  lizongyang
     *  web     www.lizongyang.cn
     *  email    1638500136
     ***/
     function DownloadFile($fileName){
        ob_end_clean();
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Length: ' . filesize($fileName));
        header('Content-Disposition: attachment; filename=' . basename($fileName));
        readfile($fileName);
    }

}
//公共函数
//获取文件修改时间
function getfiletime($file, $DataDir) {
    $a = filemtime($DataDir . $file);
    $time = date("Y-m-d H:i:s", $a);
    return $time;
}

//获取文件的大小
function getfilesize($file, $DataDir) {
    $perms = stat($DataDir . $file);
    $size = $perms['size'];
    // 单位自动转换函数
    $kb = 1024;         // Kilobyte
    $mb = 1024 * $kb;   // Megabyte
    $gb = 1024 * $mb;   // Gigabyte
    $tb = 1024 * $gb;   // Terabyte

    if ($size < $kb) {
        return $size . " B";
    } else if ($size < $mb) {
        return round($size / $kb, 2) . " KB";
    } else if ($size < $gb) {
        return round($size / $mb, 2) . " MB";
    } else if ($size < $tb) {
        return round($size / $gb, 2) . " GB";
    } else {
        return round($size / $tb, 2) . " TB";
    }
}

?>

3 html页面  下载html页面  index.html.zip 详情如下

<include file="Public/style" />
<form method="post" action="" id="listform">
  <div class="panel admin-panel">
    <div class="panel-head"><strong class="icon-reorder"> 数据库备份列表</strong> <a href="" style="float:right; display:none;">添加字段</a></div>
    <table class="table table-hover text-center">
      <tr>
        <th width="100" style="text-align:left; padding-left:20px;">ID</th>
        <th width="30%">文件名</th>
        <th width="20%">备份时间</th>
        <th width="10%">文件大小</th>
        <th width="10%">操作</th>
      </tr>
       <foreach name="lists" key="key" item="row">
            <if condition="$key gt 1">
                <tr>
                    <td>{$key-1}</td>
                    <td ><a href="{:U('Bak/index',array('Action'=>'download','file'=>$row))}">{$row}</a></td>
                    <td>{$row|getfiletime=$datadir}</td>
                    <td>{$row|getfilesize=$datadir}</td>
                    <td>
                        <td><div class="button-group"> 
                        <a class="button border-main" href="{:U('Bak/index',array('Action'=>'download','file'=>$row))}" onclick="edit({$v['id']});">下载</a>
                        <a class="button border-main" onclick="return confirm('确定将数据库还原到当前备份吗?')"href="{:U('Bak/index',array('Action'=>'RL','File'=>$row))}" >还原</a>
                        <a class="button border-red" onclick="return confirm('确定删除该备份文件吗?')"href="{:U('Bak/index',array('Action'=>'Del','File'=>$row))}"> 删除</a> </div></td>

                    </td>
                </tr>
            </if>
        </foreach>
          
      <tr>
      </tr>
      <tr>
        <td colspan="8"><div class="pagelist" style="float: left;"> <a style="margin-left: 50px;" class="btn" type="button" onClick="location.href = '__URL__/index/Action/backup'">备份添加</a></div></td>
      </tr>
          
  • 相关文章
  • Mac 如何关闭自带的Apache

    安装XAMPP后,启动服务时提示Apache启动失败,80端口被占用.查看进程发现存在几个httpd. OS X自带Apache,可是默认是没有启动的.我也没有开启Web共享,怎么就开机启动了呢? 不知道是不是因为安装了别的什么软件导致的.一般的开机启动项可以在System Preferences–Users&Groups–Login Items中添加或删除.可是在这里也没有发现Apache相关的启动项.于是谷歌到了下面一个可行的方法,打开终端,执行下面的命令.

  • LNMP环境下WordPress网站二级目录伪静态设置

    今天在给客户网站做二级目录的分类,网站一直报错404,显示应该是伪静态问题。看了下LNMP环境里的WordPress规则,貌似没有支持二级目录的。所以只好自己加一个了。目前VPS主机中使用LNMP一键安装包搭建的环境都没有带二级目录的规则。有需要的朋友可以复制下面的代码,可以让wordpress完美使用伪静态的设置。找到”/usr/local/nginx/conf/wordpress.conf”文件,然后添加:

  • 一个程序员的自白:我为什么写博客

    尝试和接触的知识一多, 便发现自己的脑袋跟硬盘相比, 速度和精准度上都差得不止一星半点. 事情越来越多, 且没有交集, 所有的知识点都零散的分布在脑袋的不同次元, 想要回忆起来特别困难. 一度让我觉得, 学越来越多的东西根本就是一个错误, 正确的方式应该是瞅准一个东西, 精益求精. 虽然这么想, 但是工作不是你想不做就不做的.

  • PHP中把stdClass Object转array的几个方法

    我们在经常使用API接口获取数据返回json数值的时候,往往单纯通过json_decode方法解析获得得数值一般并非数组,而是带有stdClass Objec的对象字符串,这时如果我们想获取相应的PHP数组时,需通过以下几种方法来获取。

  • PHP验证类库_收集开发常用验证方法

    我们在开发项目的时候往往会通过PHP的正则方式来判断用户所输入的信息是否合格或者正确,下面我给大家收集和整理成一个类,供大家参考和使用。如有问题请留言谈论。

文章评论

博客名片

职业:PHP程序员

现居:河南省-洛阳市

博客地址:www.lizongyang.cn

Email:5708837@qq.com

站点信息

  • 建站时间:2019-03-25
  • 网站程序:李宗洋博客
  • 联系电话:15888888888
  • 文章统计4084篇文章
  • 标签管理标签云
  • 微信公众号:扫描二维码,关注我们

打赏本站

  • 如果你觉得本站很棒,可以通过扫码支付打赏哦!
  • 微信扫码:你说多少就多少~
  • 支付宝扫码:你说多少就多少~

客服在线

服务时间

周一至周日 9:00-21:00