大致步骤如下:
从数据库中拿到要备份的数据表
//拿数据表
$sql = 'show tables';
$tables_in_db = Db::query($sql);//你需要一个模型 (没有?下面附一个 这里是Tp5的模型)
dump($tables_in_db);//打印
下面是打印结果
//遍历这个数组 调整一下结构 最后得到一个包含表名称的索引数组
$tables = array();
foreach ( $tables_in_db as $k =>$v )
{
$tables[$k] = $v['Tables_in_'.$dbname];//$dbname 是xxx 则键名是 Tables_in_xxx
}
拿到表结构
$sql = "show create table `tableName`";//tableName 要查看的表名
$create_table = Db::query($sql);
dump($create_table );
打印结果如下
很关键, “Create Table” 字段里的值, 就是你的表结构!!
拿对应表的数据 (这个没什么可说的)
接下来是重点了
将表结构和对应数据记录保存到 一个名为 .sql 的文件里
还原的话就是从这个文件中拿sql语句 执行
下面是自己写的一个 一键备份, 和一键还原(很弱!=.= ,没有分包什么的)
.sql 里的文件格式是模仿 Navicat for MySQL 导出的sql 文件 来写的
顺便附一个数据库操作类
https://blog.csdn.net/csdn_zhongwu/article/details/84257921
<?php
/**
* 数据库备份
*/
class Backup
{
private $tables = array();//要备份的数据表
private $path;//文件保存路径
private $dbname;//database name;
private $model;//数据库模型对象
function __construct()
{
$this->model = new Db();//你需要一个模型 请自行解决
$this->path = ROOT.'/sql/';//常量ROOT 定义的项目根目录 请自行解决
$this->dbname = DB_DBNAME;// database 名称 请自行解决
$this->check_path();
$this->get_tables();
}
//备份方法
public function backupAll ()
{
if( $this->tables )
{
$data = $this->genTitle();
foreach ( $this ->tables as $table )
{
//拿相关 create table 数据
$ctable = $this->get_create_table($table);
//生成表结构
$data .= $this->get_table_structure($ctable);
//表记录
$data .= $this->get_table_records($table);
}
$filename = $this->path . time() .'.sql';
return file_put_contents($filename, $data);
}
}
//还原方法 拆分sql语句, 因为之前保存到文件中的语句都是以 ;\r\n 结尾的, 所以...
public function restore ($file)
{
$filename = $file;
if( !file_exists($filename) )
{
return false;
}
$str = fread( $hd = fopen($filename, "rb") , filesize($filename) );
$sqls = explode(";\r\n", $str);//所以... 这里拆分sql
if($sqls)
{
foreach($sqls as $sql)
{
$this->model ->query($sql);//逐条执行
}
}
fclose($hd);
return true;
}
//备份文件相关
public function getFileInfo()
{
$temp = array();
if( is_dir($this->path) )
{
$handler = opendir($this->path);
$num = 0;
while ( $file = readdir($handler) ){
if( $file !== '.' && $file !== '..' )
{
$filename = $this->path.$file;
$temp[$num]['name'] = $file;
$temp[$num]['size'] = ceil(filesize($filename)/1024);
$temp[$num]['time'] = date("Y-m-d H:i:s" ,filemtime($filename));
$temp[$num]['path'] = $filename;
$num ++;
}
}
}
return $temp;
}
//删除文件
public function delFile ($file)
{
if( file_exists($file) )
{
return unlink($file);
}
return false;
}
//sql 文件开头部分 可以省略 但 SET FOREIGN_KEY_CHECKS=0 最好有
private function genTitle()
{
$time = date("Y-m-d H:i:s" ,time());
$str = "/*************************\r\n";
$str.= " * {$time} \r\n";
$str.= " ************************/\r\n";
$str.= "SET FOREIGN_KEY_CHECKS=0;\r\n";
return $str;
}
private function get_tables ()
{
$sql = 'show tables';
if( $data = $this->model ->fetchAll($sql) ) {
foreach ( $data as $val ) {
$this->tables[] = $val['Tables_in_'.$this->dbname];
}
}
}
//返回一个数组, 0=>表名称 ,1=>表结构(Create Table)
private function get_create_table ($table)
{
$sql = "show create table $table";
$arr = $this->model ->fetchOne($sql);
return array_values($arr);
}
//生成表结构
private function get_table_structure ($ctable)
{
$str = "-- ----------------------------\r\n";
$str .= "-- Table structure for `{$ctable[0]}`\r\n";
$str .= "-- ----------------------------\r\n";
$str .= "DROP TABLE IF EXISTS `{$ctable[0]}`;\r\n".$ctable[1].";\r\n\r\n";
return $str;
}
//表记录的sql语句拼接 当还原的时候 就是逐条插入记录 到对应的表
private function get_table_records ($table)
{
$sql = "select * from {$table}";
if( $data = $this->model ->fetchAll($sql) ) {
$str = "-- ----------------------------\r\n";
$str.= "-- Records of $table \r\n";
$str.= "-- ----------------------------\r\n";
foreach ( $data as $val ) {
if( $val ) {
//$keyArr = array();
$valArr = array();
//这里看情况了,
foreach ( $val as $k => $v ) {
//$keyArr[] = "`".$k."`";
//对单引号和换行符进行一下转义
$valArr[] = "'".str_replace( array("'","\r\n"), array("\'","\\r\\n"), $v )."'";
}
//$keys = implode(', ', $keyArr);
$values = implode(', ', $valArr);
$str .= "INSERT INTO `{$table}` VALUES ($values);\r\n";//省略了字段名称
}
}
$str .= "\r\n";
return $str;
}
return '';
}
private function check_path ()
{
if( !is_dir($this->path) ) {
mkdir($this->path ,0777 ,true);
}
}
}