123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- <?php
- /**
- * 备份数据库的扩展类
- */
- namespace org;
- use think\Db;
- use think\Config;
- class Baksql {
- private $config=[];
- private $handler;
- private $tables = array();//需要备份的表
- private $begin; //开始时间
- private $error;//错误信息
- public function __construct($config,$folder,$version) {
- //保存数据库文件路径
- $config['path'] = $folder.'/';
- //数据库文件名称
- $config["sqlbakname"] = $version.'.sql';
- $this->config = $config;
- $this->begin = microtime(true);
- header("Content-type: text/html;charset=utf-8");
- $this->connect();
- }
- //
- private function connect() {
- $this->handler = Db::connect();
- }
- /**
- * 查询
- * @param string $sql
- * @return mixed
- */
- private function query($sql = '')
- {
- $list = $this->handler->query($sql);
- return $list;
- }
- /**
- * 获取全部表
- * @param string $dbName
- * @return array
- */
- private function get_dbname($dbName = '*') {
- $sql = 'SHOW TABLES';
- $list = $this->query($sql);
- $tables = array();
- foreach ($list as $value)
- {
- $tables[] = $value['Tables_in_'.\think\facade\Config::get('database.database')];
- }
- return $tables;
- }
- /**
- * 获取表定义语句
- * @param string $table
- * @return mixed
- */
- private function get_dbhead($table = '')
- {
- $sql = "SHOW CREATE TABLE `".$table."`";
- $ddl = $this->query($sql)[0]['Create Table'] . ';';
- return $ddl;
- }
- /**
- * 获取表数据
- * @param string $table
- * @return mixed
- */
- private function get_dbdata($table = '')
- {
- $sql = "SHOW COLUMNS FROM `".$table."`";
- $list = $this->query($sql);
- //字段
- $columns = '';
- //需要返回的SQL
- $query = '';
- foreach ($list as $value)
- {
- $columns .= "`".$value['Field']."`,";
- }
- $columns = substr($columns, 0, -1);
- $data = $this->query("SELECT * FROM `".$table."`");
- foreach ($data as $value)
- {
- $dataSql = '';
- foreach ($value as $v)
- {
- $dataSql .= "'".$v."',";
- }
- $dataSql = substr($dataSql, 0, -1);
- $query .= "INSERT INTO `".$table."` ({$columns}) VALUES ({$dataSql});\r\n";
- }
- return $query;
- }
- /**
- * 写入文件
- * @param array $tables
- * @param array $ddl
- * @param array $data
- */
- private function writeToFile($tables = array(), $ddl = array(), $data = array())
- {
- $str = "/*\r\nMySQL Database Backup Tools\r\n";
- $str .= "Server:{$this->config['hostname']}:{$this->config['hostport']}\r\n";
- $str .= "Database:{$this->config['database']}\r\n";
- $str .= "Data:" . date('Y-m-d H:i:s', time()) . "\r\n*/\r\n";
- $str .= "SET FOREIGN_KEY_CHECKS=0;\r\n";
- $i = 0;
- foreach ($tables as $table)
- {
- $str .= "-- ----------------------------\r\n";
- $str .= "-- Table structure for {$table}\r\n";
- $str .= "-- ----------------------------\r\n";
- $str .= "DROP TABLE IF EXISTS `{$table}`;\r\n";
- $str .= $ddl[$i] . "\r\n";
- $str .= "-- ----------------------------\r\n";
- $str .= "-- Records of {$table}\r\n";
- $str .= "-- ----------------------------\r\n";
- $str .= $data[$i] . "\r\n";
- $i++;
- }
- if(!file_exists($this->config['path'])){mkdir($this->config['path']);}
- return file_put_contents($this->config['path'].$this->config['sqlbakname'], $str) ? true : false;
- }
- /**
- * 设置要备份的表
- * @param array $tables
- */
- private function setTables($tables = array())
- {
- if (!empty($tables) && is_array($tables))
- {
- //备份指定表
- $this->tables = $tables;
- }
- else
- {
- //备份全部表
- $this->tables = $this->get_dbname();
- }
- }
- /**
- * 备份
- * @param array $tables
- * @return bool
- */
- public function backup($tables = array())
- {
- //存储表定义语句的数组
- $ddl = array();
- //存储数据的数组
- $data = array();
- $this->setTables($tables);
- if (!empty($this->tables))
- {
- foreach ($this->tables as $table)
- {
- $ddl[] = $this->get_dbhead($table);
- $data[] = $this->get_dbdata($table);
- }
- //开始写入
- return $this->writeToFile($this->tables, $ddl, $data);
- }
- else
- {
- $this->error = '数据库中没有表!';
- return false;
- }
- }
- /**
- * 错误信息
- * @return mixed
- */
- public function getError()
- {
- return $this->error;
- }
- public function restore($filename = '')
- {
- $path=$this->config['path'].$filename;
- if (!file_exists($path))
- {
- $this->error('SQL文件不存在!');
- return false;
- }
- else
- {
- $sql = $this->parseSQL($path);
- //dump($sql);die;
- try
- {
- $this->handler->exec($sql);
- echo '还原成功!花费时间', round(microtime(true) - $this->begin,2) . 'ms';
- }
- catch (PDOException $e)
- {
- $this->error = $e->getMessage();
- return false;
- }
- }
- }
- /**
- * 解析SQL文件为SQL语句数组
- * @param string $path
- * @return array|mixed|string
- */
- private function parseSQL($path = '')
- {
- $sql = file_get_contents($path);
- $sql = explode("\r\n", $sql);
- //先消除--注释
- $sql = array_filter($sql, function ($data)
- {
- if (empty($data) || preg_match('/^--.*/', $data))
- {
- return false;
- }
- else
- {
- return true;
- }
- });
- $sql = implode('', $sql);
- //删除/**/注释
- $sql = preg_replace('/\/\*.*\*\//', '', $sql);
- return $sql;
- }
- /**
- * 下载备份
- * @param string $fileName
- * @return array|mixed|string
- */
- public function downloadFile($fileName) {
- $fileName=$this->config['path'].$fileName;
- if (file_exists($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);
- }else{
- $this->error="文件有错误!";
- }
- }
- /**
- * 获取文件是时间
- * @param string $file
- * @return string
- */
- private function getfiletime($file){
- $path=$this->config['path'].$file;
- $a = filemtime($path);
- $time = date("Y-m-d H:i:s", $a);
- return $time;
- }
- /**
- * 获取文件是大小
- * @param string $file
- * @return string
- */
- private function getfilesize($file){
- $perms=stat($this->config['path'].$file);
- $size = $perms['size'];
- $a = ['B', 'KB', 'MB', 'GB', 'TB'];
- $pos = 0;
- while ($size >= 1024) {
- $size /= 1024;
- $pos++;
- }
- return round($size, 2). $a[$pos];
- }
- /**
- * 获取文件列表
- * @param string $Order 级别
- * @return array
- */
- public function get_filelist($Order = 0) {
- $FilePath=$this->config['path'];
- // print_r($FilePath);die;
- $FilePath = opendir($FilePath);
- // $FilePath = scandir($FilePath);
- $FileAndFolderAyy=array();
- $i=1;
- while (false !== ($filename = readdir($FilePath))) {
- if ($filename!="." && $filename!=".."){
- $i++;
- $FileAndFolderAyy[$i]['name'] = $filename;
- $FileAndFolderAyy[$i]['time'] = $this->getfiletime($filename);
- $FileAndFolderAyy[$i]['size'] = $this->getfilesize($filename);
- }
- }
- $Order == 0 ? sort($FileAndFolderAyy) : rsort($FileAndFolderAyy);
- return $FileAndFolderAyy;
- }
- public function delfilename($filename){
- $path=$this->config['path'].$filename;
- if (@unlink($path)) {return '删除成功';}
- }
- }
- ?>
|