后台模块有处需求是,用户可以在界面进行数据库的备份和恢复,由于以前在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);
}
}
// 获取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;
}