备份数据库
来源:互联网 发布:云计算未来发展趋势 编辑:程序博客网 时间:2024/05/22 02:30
全写在模块内了,可备份整个库,也可以选择部分表备份
纠正一处错误,361行empty 用错了
<?phpclass BaksqlAction extends CommonAction { public $config = ''; //相关配置 public $model = ''; //实例化一个model public $content; //内容 public $dbName = ''; //数据库名 public $dir_sep = '/'; //路径符号 //初始化数据 function _initialize() { parent::_initialize(); header("Content-type: text/html;charset=utf-8"); set_time_limit(0); //不超时 ini_set('memory_limit','500M'); $this->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 < 1024 ? number_format($fileSize, 2) . ' KB' : 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 < $byte) { $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; }}?>
- 备份数据库
- 备份数据库
- 数据库备份
- 数据库备份
- 数据库备份
- 数据库备份
- 备份数据库
- 数据库备份
- 备份数据库
- 数据库备份
- 数据库备份
- 备份数据库
- 数据库备份
- 数据库备份
- 数据库备份
- 数据库备份
- 数据库备份
- 数据库备份
- 随机数的产生rand( ) 和srand( )
- Google翻译插件
- 黑马程序员--JavaJAVA 正则表达式 (超详细)
- 用MongoDB的文档结构描述数据关系
- concatenate std::string 和int的
- 备份数据库
- Ogre的材质
- 获取一定范围内的随机数字
- 秒杀排列组合(上)————排列篇
- thinkphp3.12无限级留言与回复的留言板模块
- Sprite的长和宽
- android am介绍
- poj 2524(并查集-求连通子集的个数)
- 黑马程序员---异常处理机制