| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- <?php
- namespace app\admin\controller;
- use think\Db;
- use app\common\util\Dir;
- use app\common\util\Database as dbOper;
- class Database extends Base
- {
- var $_db_config;
- public function __construct()
- {
- parent::__construct();
- }
- public function index()
- {
- $group = input('group');
- if($group=='import'){
- //列出备份文件列表
- $path = trim( $GLOBALS['config']['db']['backup_path'], '/').DS;
- if (!is_dir($path)) {
- Dir::create($path);
- }
- $flag = \FilesystemIterator::KEY_AS_FILENAME;
- $glob = new \FilesystemIterator($path, $flag);
- $list = [];
- foreach ($glob as $name => $file) {
- if(preg_match('/^\d{8,8}-\d{6,6}-\d+\.sql(?:\.gz)?$/', $name)){
- $name = sscanf($name, '%4s%2s%2s-%2s%2s%2s-%d');
- $date = "{$name[0]}-{$name[1]}-{$name[2]}";
- $time = "{$name[3]}:{$name[4]}:{$name[5]}";
- $part = $name[6];
- if(isset($list["{$date} {$time}"])){
- $info = $list["{$date} {$time}"];
- $info['part'] = max($info['part'], $part);
- $info['size'] = $info['size'] + $file->getSize();
- } else {
- $info['part'] = $part;
- $info['size'] = $file->getSize();
- }
- $extension = strtoupper($file->getExtension());
- $info['compress'] = ($extension === 'SQL') ? '无' : $extension;
- $info['time'] = strtotime("{$date} {$time}");
- $list["{$date} {$time}"] = $info;
- }
- }
- }
- else{
- $group='export';
- $list = Db::query("SHOW TABLE STATUS");
- }
- $this->assign('list',$list);
- $this->assign('title',lang('admin/database/title'));
- return $this->fetch('admin@database/'.$group);
- }
- public function export($ids = '', $start = 0)
- {
- if ($this->request->isPost()) {
- if (empty($ids)) {
- return $this->error(lang('admin/database/select_export_table'));
- }
- if (!is_array($ids)) {
- $tables[] = $ids;
- } else {
- $tables = $ids;
- }
- $have_admin = false;
- $admin_table='';
- foreach($tables as $k=>$v){
- if(strpos($v,'_admin')!==false){
- $have_admin=true;
- $admin_table = $v;
- unset($tables[$k]);
- }
- }
- if($have_admin){
- $tables[] = $admin_table;
- }
- //读取备份配置
- $config = array(
- 'path' => $GLOBALS['config']['db']['backup_path'] .DS,
- 'part' => $GLOBALS['config']['db']['part_size'] ,
- 'compress' => $GLOBALS['config']['db']['compress'] ,
- 'level' => $GLOBALS['config']['db']['compress_level'] ,
- );
- //检查是否有正在执行的任务
- $lock = "{$config['path']}backup.lock";
- if(is_file($lock)){
- return $this->error(lang('admin/database/lock_check'));
- } else {
- if (!is_dir($config['path'])) {
- Dir::create($config['path'], 0755, true);
- }
- //创建锁文件
- file_put_contents($lock, $this->request->time());
- }
- //生成备份文件信息
- $file = [
- 'name' => date('Ymd-His', $this->request->time()),
- 'part' => 1,
- ];
- // 创建备份文件
- $database = new dbOper($file, $config);
- if($database->create() !== false) {
- // 备份指定表
- foreach ($tables as $table) {
- $start = $database->backup($table, $start);
- while (0 !== $start) {
- if (false === $start) {
- return $this->error(lang('admin/database/backup_err'));
- }
- $start = $database->backup($table, $start[0]);
- }
- }
- // 备份完成,删除锁定文件
- unlink($lock);
- }
- return $this->success(lang('admin/database/backup_ok'));
- }
- return $this->error(lang('admin/database/backup_err'));
- }
- /**
- * 恢复数据库 [参考原作者 麦当苗儿 <[email protected]>]
- * @param string|array $ids 表名
- * @param integer $start 起始行数
- * @author 橘子俊 <[email protected]>
- * @return mixed
- */
- public function import($id = '')
- {
- if (empty($id)) {
- return $this->error(lang('admin/database/select_file'));
- }
- $name = date('Ymd-His', $id) . '-*.sql*';
- $path = trim( $GLOBALS['config']['db']['backup_path'] , '/').DS.$name;
- $files = glob($path);
- $list = array();
- foreach($files as $name){
- $basename = basename($name);
- $match = sscanf($basename, '%4s%2s%2s-%2s%2s%2s-%d');
- $gz = preg_match('/^\d{8,8}-\d{6,6}-\d+\.sql.gz$/', $basename);
- $list[$match[6]] = array($match[6], $name, $gz);
- }
- ksort($list);
- // 检测文件正确性
- $last = end($list);
- if(count($list) === $last[0]){
- foreach ($list as $item) {
- $config = [
- 'path' => trim($GLOBALS['config']['db']['backup_path'], '/').DS,
- 'compress' => $item[2]
- ];
- $database = new dbOper($item, $config);
- $start = $database->import(0);
- // 导入所有数据
- while (0 !== $start) {
- if (false === $start) {
- return $this->error(lang('admin/database/import_err'));
- }
- $start = $database->import($start[0]);
- }
- }
- return $this->success(lang('admin/database/import_ok'));
- }
- return $this->error(lang('admin/database/file_damage'));
- }
- public function optimize($ids = '')
- {
- if (empty($ids)) {
- return $this->error(lang('admin/database/select_optimize_table'));
- }
- if (!is_array($ids)) {
- $table[] = $ids;
- } else {
- $table = $ids;
- }
- $tables = implode('`,`', $table);
- $res = Db::query("OPTIMIZE TABLE `{$tables}`");
- if ($res) {
- return $this->success(lang('admin/database/optimize_ok'));
- }
- return $this->error(lang('admin/database/optimize_err'));
- }
- public function repair($ids = '')
- {
- if (empty($ids)) {
- return $this->error(lang('admin/database/select_repair_table'));
- }
- if (!is_array($ids)) {
- $table[] = $ids;
- } else {
- $table = $ids;
- }
- $tables = implode('`,`', $table);
- $res = Db::query("REPAIR TABLE `{$tables}`");
- if ($res) {
- return $this->success(lang('admin/database/repair_ok'));
- }
- return $this->error(lang('admin/database/repair_ok'));
- }
- public function del($id = '')
- {
- if (empty($id)) {
- return $this->error(lang('admin/database/select_del_file'));
- }
- $name = date('Ymd-His', $id) . '-*.sql*';
- $path = trim($GLOBALS['config']['db']['backup_path']).DS.$name;
- array_map("unlink", glob($path));
- if(count(glob($path)) && glob($path)){
- return $this->error(lang('del_err'));
- }
- return $this->success(lang('del_ok'));
- }
- public function sql()
- {
- if($this->request->isPost()){
- $param=input();
- $validate = \think\Loader::validate('Token');
- if(!$validate->check($param)){
- return $this->error($validate->getError());
- }
- $sql = trim($param['sql']);
- if(!empty($sql)){
- $sql = str_replace('{pre}',config('database.prefix'),$sql);
- //查询语句返回结果集
- if(strtolower(substr($sql,0,6))=="select"){
- }
- else{
- Db::execute($sql);
- }
- }
- $this->success(lang('run_ok'));
- }
- return $this->fetch('admin@database/sql');
- }
- public function columns()
- {
- $param = input();
- $table = $param['table'];
- if(!empty($table)){
- $list = Db::query('SHOW COLUMNS FROM '.$table);
- $this->success(lang('obtain_ok'),null, $list);
- }
- $this->error(lang('param_err'));
- }
- public function rep()
- {
- if($this->request->isPost()){
- $param = input();
- $table = $param['table'];
- $field = $param['field'];
- $findstr = $param['findstr'];
- $tostr = $param['tostr'];
- $where = $param['where'];
- $validate = \think\Loader::validate('Token');
- if(!$validate->check($param)){
- return $this->error($validate->getError());
- }
- if(!empty($table) && !empty($field) && !empty($findstr) && !empty($tostr)){
- $sql = "UPDATE ".$table." set ".$field."=Replace(".$field.",'".$findstr."','".$tostr."') where 1=1 ". $where;
- Db::execute($sql);
- return $this->success(lang('run_ok'));
- }
- return $this->error(lang('param_err'));
- }
- $list = Db::query("SHOW TABLE STATUS");
- $this->assign('list',$list);
- return $this->fetch('admin@database/rep');
- }
- public function inspect()
- {
- $param = input();
- if ($param['ck']) {
- $pre = config('database.prefix');
- $schema = Db::query('select * from information_schema.columns where table_schema = ?', [config('database.database')]);
- $col_list = [];
- $sql = '';
- foreach ($schema as $k => $v) {
- $col_list[$v['TABLE_NAME']][$v['COLUMN_NAME']] = $v;
- }
- $tables = ['actor', 'art', 'gbook', 'link', 'topic', 'type', 'vod'];
- $param['tbi'] = intval($param['tbi']);
- if ($param['tbi'] >= count($tables)) {
- mac_echo(lang('admin/database/clear_ok'));
- die;
- }
- $check_arr = ["<script>", "<iframe>"];
- $rel_val = ["/<script[\s\S]*?<\/script>/is","/<iframe[\s\S]*?<\/iframe>/is"];
- mac_echo('<style type="text/css">body{font-size:12px;color: #333333;line-height:21px;}span{font-weight:bold;color:#FF0000}</style>');
- foreach ($col_list as $k1 => $v1) {
- $pre_tb = str_replace($pre, '', $k1);
- $si = array_search($pre_tb, $tables);
- if ($pre_tb !== $tables[$param['tbi']]) {
- continue;
- }
- mac_echo(lang('admin/database/check_tip1',[$k1]));
- $where = [];
- foreach ($v1 as $k2 => $v2) {
- if (strpos($v2['DATA_TYPE'], 'int') === false) {
- $where[$k2] = ['like', mac_like_arr(join(',', $check_arr)), 'OR'];
- }
- }
- if (!empty($where)) {
- $field = array_keys($where);
- $field[] = $tables[$si] . '_id';
- $list = Db::name($pre_tb)->field($field)->whereOr($where)->fetchSql(false)->select();
- mac_echo(lang('admin/database/check_tip2',[count($list)]));
- foreach ($list as $k3 => $v3) {
- $update = [];
- $col_id = $tables[$si] . '_id';
- $col_name = $tables[$si] . '_name';
- $val_id = $v3[$col_id];;
- $val_name = strip_tags($v3[$col_name]);
- $ck = false;
- $where2 = [];
- $where2[$col_id] = $val_id;
- foreach ($v3 as $k4 => $v4) {
- if ($k4 != $col_id) {
- $val = $v4;
- foreach ($check_arr as $kk => $vv) {
- $val = preg_replace($rel_val[$kk], "", $val);
- }
- if ($val !== $v4) {
- $update[$k4] = $val;
- $ck = true;
- }
- }
- }
- if ($ck) {
- $r = Db::name($pre_tb)->where($where2)->update($update);
- mac_echo($val_id . '、' . $val_name . ' ok');
- }
- }
- }
- }
- $param['tbi']++;
- $url = url('database/inspect') . '?' . http_build_query($param);
- mac_jump($url, 3);
- exit;
- }
- return $this->fetch('admin@database/inspect');
- }
- }
|