心理咨询网
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

DatabaseController.php 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. /**
  3. * @copyright (C)2016-2099 Hnaoyun Inc.
  4. * @author XingMeng
  5. * @email hnxsh@foxmail.com
  6. * @date 2017年5月9日
  7. * 数据库管理,只支持MySQL
  8. */
  9. namespace app\admin\controller\system;
  10. use core\basic\Controller;
  11. use app\admin\model\system\DatabaseModel;
  12. class DatabaseController extends Controller
  13. {
  14. private $model;
  15. private $dbauth;
  16. function __construct()
  17. {
  18. $this->model = new DatabaseModel();
  19. $this->dbauth = $this->config('database');
  20. }
  21. // 数据库管理
  22. public function index()
  23. {
  24. switch ($this->dbauth['type']) {
  25. case 'mysqli':
  26. case 'pdo_mysql':
  27. $this->assign('db', 'mysql');
  28. $this->assign('tables', $this->model->getList());
  29. break;
  30. case 'sqlite':
  31. case 'pdo_sqlite':
  32. $this->assign('db', 'sqlite');
  33. break;
  34. default:
  35. error('当前配置的数据库类型不支持在线管理!');
  36. }
  37. $this->display('system/database.html');
  38. }
  39. // 数据库修改
  40. public function mod()
  41. {
  42. if (! $_POST) {
  43. alert_back('非法访问!', - 1);
  44. }
  45. $submit = post('submit', 'letter', true);
  46. switch ($submit) {
  47. case 'yh':
  48. $tables = self::getTableList();
  49. if (! $tables)
  50. alert_back('请选择数据表!');
  51. if ($this->model->optimize(implode(',', $tables))) {
  52. // $this->log('优化数据库表成功!');
  53. success('优化成功!', - 1);
  54. } else {
  55. // $this->log('优化数据库表失败!');
  56. error('优化失败!', - 1);
  57. }
  58. break;
  59. case 'xf':
  60. $tables = self::getTableList();
  61. if (! $tables)
  62. alert_back('请选择数据表!');
  63. if ($this->model->repair(implode(',', $tables))) {
  64. // $this->log('修复数据库表成功!');
  65. success('修复成功!', - 1);
  66. } else {
  67. // $this->log('修复数据库表失败!');
  68. error('修复失败!', - 1);
  69. }
  70. break;
  71. case 'bf':
  72. $tables = self::getTableList();
  73. if (! $tables)
  74. alert_back('请选择数据表!');
  75. if ($this->backupTable($tables)) {
  76. $this->log('备份数据库表成功!');
  77. success('备份表成功!', - 1);
  78. } else {
  79. $this->log('备份数据库表失败!');
  80. error('备份失败!', - 1);
  81. }
  82. break;
  83. case 'bfdb':
  84. if ($this->backupDB()) {
  85. $this->log('备份数据库成功!');
  86. success('备份数据库成功!', - 1);
  87. } else {
  88. $this->log('备份数据库失败!');
  89. error('备份失败!', - 1);
  90. }
  91. break;
  92. case 'bfsqlite':
  93. if (copy(DOC_PATH . $this->dbauth['dbname'], DOC_PATH . STATIC_DIR . '/backup/sql/' . get_uniqid() . '_' . date('YmdHis') . '.db')) {
  94. $this->log('备份数据库成功!');
  95. success('备份数据库成功!', - 1);
  96. } else {
  97. $this->log('备份数据库失败!');
  98. error('备份失败!', - 1);
  99. }
  100. break;
  101. }
  102. }
  103. // 备份数据表
  104. public function backupTable($tables)
  105. {
  106. $backdir = date('YmdHis');
  107. foreach ($tables as $table) {
  108. $sql = '';
  109. $sql .= $this->header(); // 备份文件头部说明
  110. $sql .= $this->tableSql($table); // 表结构信息
  111. $fields = $this->model->getFields($table); // 表字段
  112. $field_num = $this->model->getFieldNum($table); // 字段数量
  113. $all_data = $this->model->getAll($table); // 读取全部数据
  114. $sql .= $this->dataSql($table, $fields, $field_num, $all_data); // 生成语句
  115. $filename = $backdir . "/" . get_uniqid() . "_" . $backdir . "_" . $table . '.sql'; // 写入文件
  116. $result = $this->writeFile($filename, $sql);
  117. }
  118. return $result;
  119. }
  120. // 备份整个数据库
  121. public function backupDB()
  122. {
  123. $sql = '';
  124. $sql .= $this->header(); // 备份文件头部说明
  125. $sql .= $this->dbSql(); // 数据库创建语句
  126. $tables = $this->model->getTables(); // 获取所有表
  127. foreach ($tables as $table) { // 表结构及数据
  128. $sql .= $this->tableSql($table); // 表结构信息
  129. $fields = $this->model->getFields($table); // 表字段
  130. $field_num = $this->model->getFieldNum($table); // 字段数量
  131. $all_data = $this->model->getAll($table); // 读取全部数据
  132. if ($all_data) {
  133. $sql .= $this->dataSql($table, $fields, $field_num, $all_data); // 生成数据语句
  134. }
  135. $sql .= '-- --------------------------------------------------------' . PHP_EOL . PHP_EOL;
  136. }
  137. // 写入文件
  138. $filename = get_uniqid() . '_' . date('YmdHis') . '_' . $this->dbauth['dbname'] . '.sql';
  139. return $this->writeFile($filename, $sql);
  140. }
  141. // 插入数据库备份基础信息
  142. private function header()
  143. {
  144. $sql = '-- Online Database Management SQL Dump' . PHP_EOL;
  145. $sql .= '-- 数据库名: ' . $this->dbauth['dbname'] . PHP_EOL;
  146. $sql .= '-- 生成日期: ' . date('Y-m-d H:i:s') . PHP_EOL;
  147. $sql .= '-- PHP 版本: ' . phpversion() . PHP_EOL . PHP_EOL;
  148. $sql .= 'SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";' . PHP_EOL;
  149. $sql .= 'SET time_zone = "+08:00";' . PHP_EOL;
  150. $sql .= 'SET NAMES utf8;' . PHP_EOL . PHP_EOL;
  151. $sql .= '-- --------------------------------------------------------' . PHP_EOL . PHP_EOL;
  152. return $sql;
  153. }
  154. // 数据库创建语句
  155. private function dbSql()
  156. {
  157. $sql = '';
  158. $sql .= "--" . PHP_EOL;
  159. $sql .= "-- 数据库名 `" . $this->dbauth['dbname'] . '`' . PHP_EOL;
  160. $sql .= "--" . PHP_EOL . PHP_EOL;
  161. // 如果数据库不存在则创建
  162. $sql .= "CREATE DATABASE IF NOT EXISTS `" . $this->dbauth['dbname'] . '` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;' . PHP_EOL;
  163. // 选择数据库
  164. $sql .= "USE `" . $this->dbauth['dbname'] . "`;" . PHP_EOL . PHP_EOL;
  165. $sql .= '-- --------------------------------------------------------' . PHP_EOL . PHP_EOL;
  166. return $sql;
  167. }
  168. // 表结构语句
  169. private function tableSql($table)
  170. {
  171. $sql = '';
  172. $sql .= "--" . PHP_EOL;
  173. $sql .= "-- 表的结构 `" . $table . '`' . PHP_EOL;
  174. $sql .= "--" . PHP_EOL . PHP_EOL;
  175. $sql .= $this->model->tableStru($table); // 表创建语句
  176. return $sql;
  177. }
  178. // 数据语句
  179. private function dataSql($table, $fields, $fieldNnum, $data)
  180. {
  181. if (! $data)
  182. return;
  183. $sql = '';
  184. $sql .= "--" . PHP_EOL;
  185. $sql .= "-- 转存表中的数据 `" . $table . "`" . PHP_EOL;
  186. $sql .= "--" . PHP_EOL;
  187. $sql .= PHP_EOL;
  188. // 循环每个字段下面的内容
  189. $sql .= "INSERT INTO `" . $table . "` (" . implode(',', $fields) . ") VALUES" . PHP_EOL;
  190. $brackets = "(";
  191. foreach ($data as $value) {
  192. $sql .= $brackets;
  193. $comma = "";
  194. for ($i = 0; $i < $fieldNnum; $i ++) {
  195. $sql .= ($comma . "'" . addslashes(decode_string($value[$i])) . "'");
  196. $comma = ",";
  197. }
  198. $sql .= ")";
  199. $brackets = "," . PHP_EOL . "(";
  200. }
  201. $sql .= ';' . PHP_EOL . PHP_EOL;
  202. return $sql;
  203. }
  204. // 写入文件
  205. private function writeFile($filename, $content)
  206. {
  207. $sqlfile = DOC_PATH . STATIC_DIR . '/backup/sql/' . $filename;
  208. check_file($sqlfile, true);
  209. if (file_put_contents($sqlfile, $content)) {
  210. return true;
  211. }
  212. }
  213. // 获取并检查表名称
  214. private function getTableList()
  215. {
  216. $list = post('list');
  217. foreach ($list as $key => $value) {
  218. if (! preg_match('/^[\w]+$/', $value)) {
  219. unset($list[$key]);
  220. }
  221. }
  222. return $list;
  223. }
  224. }