在页面进行数据库备份和还原

后台模块有处需求是,用户可以在界面进行数据库的备份和恢复,由于以前在windows上实现过,因此这次把代码跑到linux上,遇到了一些坑,这里便记录下。


第一个坑,常用的登录mysql都是mysql -uroot -ppasswd即可进入,但是在linux上,如果把mysql.sock的路径改了,那么在命令行模式下是进不去的,需要加上个-S参数,后面跟着mysql.sock的路径


第二个坑,正确导入后,发现中文部分都乱码了,这时才记起需要在导入的时候,申明下字符编码--default-character-set=utf8


ok,下面把代码贴出来,以供以后参考


还原代码

    // 还原
    public function restore() {

        set_time_limit(0);

        // 是否有上传
        if ($_FILES['file']['size'] > 0) {

            $path = parent::upload(array('sql'), C('DATABASE_PATH'));
        } else {
            $this->error('请上传正确的数据库文件');
        }

        $socket = getSocket();

        $sql = C('DATABASE_PATH') . $path;
        $database = C('DB_NAME');

        // 删除原有的数据库,再重新创建
        M()->query('DROP DATABASE ' . $database);
        M()->query('CREATE DATABASE ' . $database . ' character set utf8');
        M()->query('SET NAMES utf8');


        // 判断是在Windows还是Linux
        $cmd = 'mysql -u' . C('DB_USER') . ' -p' . C('DB_PWD') . ' -S ' . $socket . ' --default-character-set=utf8 < ' . $sql;
        if (PHP_OS == 'WINNT') {
            $cmd = 'mysql -u' . C('DB_USER') . ' -p' . C('DB_PWD') . ' ' . $database . ' < ' . $sql;
        }
        exec($cmd);
        @unlink($sql);

    }


备份代码

    // 备份
    public function backup() {

        // 获取mysql的socket位置
        $socket = getSocket();

        $sql = C('DATABASE_PATH') . C('DB_NAME') . '.sql';
        if (file_exists($sql)) {
            @unlink($sql);
        }

        // 判断是在Windows还是Linux
        $cmd = 'mysqldump -u' . C('DB_USER') . ' -p' . C('DB_PWD') . ' -S ' . $socket . ' -B ' . C('DB_NAME') . ' > ' . $sql;
        if (PHP_OS == 'WINNT') {
            $cmd = 'mysqldump -u' . C('DB_USER') . ' -p' . C('DB_PWD') . ' -B ' . C('DB_NAME') . ' > ' . $sql;
        }
        exec($cmd);

        // 下载到本地
        if (file_exists($sql) && is_file($sql)) {
            // 发送 headers
            header('Cache-control: private');
            header('Content-Type: application/octet-stream');
            header('Content-Length: ' . filesize($sql));
            header('Content-Disposition: filename=' . C('DB_NAME') . '.sql');
            // flush 内容
            flush();
            // 打开文件流
            $file = fopen($sql, "r");
            while (!feof($file)) {
                // 发送当前部分文件给浏览者
                print fread($file, filesize($sql));
                // flush 内容输出到浏览器端
                flush();
                ob_flush();  //防止PHP或web服务器的缓存机制影响输出
                // 终端1秒后继续
                sleep(1);
            }
            // 关闭文件流
            fclose($file);
        }
    }



查找linux上的mysql.sock文件的路径方法

// 获取mysql的socket位置
function getSocket() {

    // 读取linux上mysql的socket的位置
    $res = fopen('/etc/my.cnf', 'r');
    $socket = '';
    if ($res) {
        while (!feof($res)) {
            $line = fgets($res);
            if (strpos($line, 'socket') === 0) {
                $socket = trim(str_replace(array('socket', '='), '', $line));
            }
        }
    }
    fclose($res);

    return $socket;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值