您的位置:首页 > 数据库

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

2014-03-31 11:06 218 查看
后台模块有处需求是,用户可以在界面进行数据库的备份和恢复,由于以前在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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: