全写在模块内了,可备份整个库,也可以选择部分表备份
纠正一处错误,361行empty 用错了
config = array(
'path' => c('db_backup'), //备份文件存在哪里
'iscompress' => 0, //是否开启gzip压缩 【未测试】
'isdownload' => 0 //备份完成后是否下载文件 【未测试】
);
$this->dbname = c('db_name'); //当前数据库名称
$this->model = new model();
//$sql = 'set interactive_timeout=24*3600'; //空闲多少秒后 断开链接
//$this->model>execute($sql);
}
/* -
* +------------------------------------------------------------------------
* * @ 已备份数据列表
* +------------------------------------------------------------------------
*/
function index() {
$path = $this->config['path'];
$filearr = $this->myscandir($path);
foreach ($filearr as $key => $value) {
if ($key > 1) {
//获取文件创建时间
$filetime = date('y-m-d h:i:s', filemtime($path . '/' . $value));
$filesize = filesize($path . '/' . $value) / 1024;
//获取文件大小
$filesize = $filesize number_format($filesize / 1024, 2) . ' mb';
//构建列表数组
$list[] = array(
'name' => $value,
'time' => $filetime,
'size' => $filesize
);
}
}
$this->assign('list', $list);
$this->display();
}
/* -
* +------------------------------------------------------------------------
* * @ 获取数据表
* +------------------------------------------------------------------------
*/
function tablist() {
$list = $this->model->query(show table status from {$this->dbname}); //得到表的信息
//echo $backup->getlastsql();
$this->assign('list', $list);
$this->display();
}
/* -
* +------------------------------------------------------------------------
* * @ 备份整个数据库
* +------------------------------------------------------------------------
*/
function backall() {
$tables = $this->gettables();
if ($this->backup($tables)) {
$this->success('数据库备份成功!', '/public/ok');
} else {
$this->error('数据库备份失败!');
}
}
/* -
* +------------------------------------------------------------------------
* * @ 按表备份,可批量
* +------------------------------------------------------------------------
*/
function backtables() {
$tab = $_request['tab'];
if (is_array($tab))
$tables = $tab;
else
$tables[] = $tab;
if ($this->backup($tables)) {
if (is_array($tab))
$this->success('数据库备份成功!');
else
$this->success('数据库备份成功!', '/public/ok');
} else {
$this->error('数据库备份失败!');
}
}
//还原数据库
function recover() {
if ($this->recover_file($_get['file'])) {
$this->success('数据还原成功!', '/public/ok');
} else {
$this->error('数据还原失败!');
}
}
//删除数据备份
function deletebak() {
if (unlink($this->config['path'] . $this->dir_sep . $_get['file'])) {
$this->success('删除备份成功!', '/public/ok');
} else {
$this->error('删除备份失败!');
}
}
/* -
* +------------------------------------------------------------------------
* * @ 下载备份文件
* +------------------------------------------------------------------------
*/
function downloadbak() {
$file_name = $_get['file'];
$file_dir = $this->config['path'];
if (!file_exists($file_dir . / . $file_name)) { //检查文件是否存在
return false;
exit;
} else {
$file = fopen($file_dir . / . $file_name, r); // 打开文件
// 输入文件标签
header('content-encoding: none');
header(content-type: application/octet-stream);
header(accept-ranges: bytes);
header(accept-length: . filesize($file_dir . / . $file_name));
header('content-transfer-encoding: binary');
header(content-disposition: attachment; filename= . $file_name); //以真实文件名提供给浏览器下载
header('pragma: no-cache');
header('expires: 0');
//输出文件内容
echo fread($file, filesize($file_dir . / . $file_name));
fclose($file);
exit;
}
}
/* -
* +------------------------------------------------------------------------
* * @ 获取 目录下文件数组
* +------------------------------------------------------------------------
* * @ $filepath 目录路径
* * @ $order 排序
* +------------------------------------------------------------------------
* * @ 获取指定目录下的文件列表,返回数组
* +------------------------------------------------------------------------
*/
private function myscandir($filepath = './', $order = 0) {
$filepath = opendir($filepath);
while ($filename = readdir($filepath)) {
$filearr[] = $filename;
}
$order == 0 ? sort($filearr) : rsort($filearr);
return $filearr;
}
/* * ******************************************************************************************** */
/* -
* +------------------------------------------------------------------------
* * @ 读取备份文件
* +------------------------------------------------------------------------
* * @ $filename 文件名
* +------------------------------------------------------------------------
*/
private function getfile($filename) {
$this->content = '';
$filename = $this->trimpath($this->config['path'] . $this->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->error('无法识别的文件格式!');
}
} else {
$this->error('文件不存在!');
}
}
/* -
* +------------------------------------------------------------------------
* * @ 把数据写入磁盘
* +------------------------------------------------------------------------
*/
private function setfile() {
$recognize = '';
$recognize = $this->dbname;
$filename = $this->trimpath($this->config['path'] . $this->dir_sep . $recognize . '_' . date('ymdhis') . '_' . mt_rand(100000000, 999999999) . '.sql');
$path = $this->setpath($filename);
if ($path !== true) {
$this->error(无法创建备份目录目录 '$path');
}
if ($this->config['iscompress'] == 0) {
if (!file_put_contents($filename, $this->content, lock_ex)) {
$this->error('写入文件失败,请检查磁盘空间或者权限!');
}
} else {
if (function_exists('gzwrite')) {
$filename .= '.gz';
if ($gz = gzopen($filename, 'wb')) {
gzwrite($gz, $this->content);
gzclose($gz);
} else {
$this->error('写入文件失败,请检查磁盘空间或者权限!');
}
} else {
$this->error('没有开启gzip扩展!');
}
}
if ($this->config['isdownload']) {
$this->downloadfile($filename);
}
}
private function trimpath($path) {
return str_replace(array('/', '\\', '//', '\\\\'), $this->dir_sep, $path);
}
private function setpath($filename) {
$dirs = explode($this->dir_sep, dirname($filename));
$tmp = '';
foreach ($dirs as $dir) {
$tmp .= $dir . $this->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);
}
/* -
* +------------------------------------------------------------------------
* * @ 给字符串添加 ` `
* +------------------------------------------------------------------------
* * @ $str 字符串
* +------------------------------------------------------------------------
* * @ 返回 `$str`
* +------------------------------------------------------------------------
*/
private function backquote($str) {
return `{$str}`;
}
/* -
* +------------------------------------------------------------------------
* * @ 获取数据库的所有表
* +------------------------------------------------------------------------
* * @ $dbname 数据库名称
* +------------------------------------------------------------------------
*/
private function gettables($dbname = '') {
if (!empty($dbname)) {
$sql = 'show tables from ' . $dbname;
} else {
$sql = 'show tables ';
}
$result = $this->model->query($sql);
$info = array();
foreach ($result as $key => $val) {
$info[$key] = current($val);
}
return $info;
}
/* -
* +------------------------------------------------------------------------
* * @ 把传过来的数据 按指定长度分割成数组
* +------------------------------------------------------------------------
* * @ $array 要分割的数据
* * @ $byte 要分割的长度
* +------------------------------------------------------------------------
* * @ 把数组按指定长度分割,并返回分割后的数组
* +------------------------------------------------------------------------
*/
private function chunkarraybybyte($array, $byte = 5120) {
$i = 0;
$sum = 0;
$return = array();
foreach ($array as $v) {
$sum += strlen($v);
if ($sum $return[$i][] = $v;
} elseif ($sum == $byte) {
$return[++$i][] = $v;
$sum = 0;
} else {
$return[++$i][] = $v;
$i++;
$sum = 0;
}
}
return $return;
}
/* -
* +------------------------------------------------------------------------
* * @ 备份数据 { 备份每张表、视图及数据 }
* +------------------------------------------------------------------------
* * @ $tables 需要备份的表数组
* +------------------------------------------------------------------------
*/
private function backup($tables) {
if (empty($tables))
$this->error('没有需要备份的数据表!');
$this->content = '/* this file is created by mysqlreback ' . date('y-m-d h:i:s') . ' */';
foreach ($tables as $i => $table) {
$table = $this->backquote($table); //为表名增加 ``
$tablers = $this->model->query(show create table {$table}); //获取当前表的创建语句
if (!empty($tablers[0][create view])) {
$this->content .= \r\n /* 创建视图结构 {$table} */;
$this->content .= \r\n drop view if exists {$table};/* mysqlreback separation */ . $tablers[0][create view] . ;/* mysqlreback separation */;
}
if (!empty($tablers[0][create table])) {
$this->content .= \r\n /* 创建表结构 {$table} */;
$this->content .= \r\n drop table if exists {$table};/* mysqlreback separation */ . $tablers[0][create table] . ;/* mysqlreback separation */;
$tabledaterow = $this->model->query(select * from {$table});
$valuesarr = array();
$values = '';
if (false != $tabledaterow) {
foreach ($tabledaterow as &$y) {
foreach ($y as &$v) {
if ($v=='') //纠正empty 为0的时候 返回tree
$v = 'null'; //为空设为null
else
$v = ' . mysql_escape_string($v) . '; //非空 加转意符
}
$valuesarr[] = '(' . implode(',', $y) . ')';
}
}
$temp = $this->chunkarraybybyte($valuesarr);
if (is_array($temp)) {
foreach ($temp as $v) {
$values = implode(',', $v) . ';/* mysqlreback separation */';
if ($values != ';/* mysqlreback separation */') {
$this->content .= \r\n /* 插入数据 {$table} */;
$this->content .= \r\n insert into {$table} values {$values};
}
}
}
// dump($this->content);
// exit;
}
}
if (!empty($this->content)) {
$this->setfile();
}
return true;
}
/* -
* +------------------------------------------------------------------------
* * @ 还原数据
* +------------------------------------------------------------------------
* * @ $filename 文件名
* +------------------------------------------------------------------------
*/
private function recover_file($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)) {
$mes = $this->model->execute($sql);
if (false === $mes) { //如果 null 写入失败,换成 ''
$table_change = array('null' => '\'\'');
$sql = strtr($sql, $table_change);
$mes = $this->model->execute($sql);
}
if (false === $mes) { //如果遇到错误、记录错误
$log_text = '以下代码还原遇到问题:';
$log_text.=\r\n $sql;
set_log($log_text);
}
}
}
} else {
$this->error('无法读取备份文件!');
}
return true;
}
}
?>
ad:真正免费,域名+虚机+企业邮箱=0元