Database.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <?php
  2. namespace app\admin\controller\general;
  3. use app\admin\model\AdminLog;
  4. use app\common\controller\Backend;
  5. use think\Db;
  6. use think\Debug;
  7. /**
  8. * 数据库管理
  9. *
  10. * @icon fa fa-database
  11. * @remark 可在线进行一些简单的数据库表优化或修复,查看表结构和数据。也可以进行SQL语句的操作
  12. */
  13. class Database extends Backend
  14. {
  15. /**
  16. * 查看
  17. */
  18. function index()
  19. {
  20. $tables_data_length = $tables_index_length = $tables_free_length = $tables_data_count = 0;
  21. $tables = $list = [];
  22. $list = Db::query("SHOW TABLES");
  23. foreach ($list as $key => $row)
  24. {
  25. $tables[] = ['name' => reset($row), 'rows' => 0];
  26. }
  27. $data['tables'] = $tables;
  28. /*
  29. $one = Db::table('configvalue')->where('name', 'sql')->find();
  30. $saved_sql = [];
  31. if ($one && $one['content'])
  32. $saved_sql = explode('###', $one['content']);
  33. $data['saved_sql'] = array_values(array_filter($saved_sql));
  34. * */
  35. $data['saved_sql'] = [];
  36. $this->view->assign($data);
  37. return $this->view->fetch();
  38. }
  39. /**
  40. * SQL查询
  41. */
  42. public function query()
  43. {
  44. $do_action = $this->request->post('do_action');
  45. echo '<style type="text/css">
  46. xmp,body{margin:0;padding:0;line-height:18px;font-size:12px;font-family:"Helvetica Neue", Helvetica, Microsoft Yahei, Hiragino Sans GB, WenQuanYi Micro Hei, sans-serif;}
  47. hr{height:1px;margin:5px 1px;background:#e3e3e3;border:none;}
  48. </style>';
  49. if ($do_action == '')
  50. exit(__('Invalid parameters'));
  51. $tablename = $this->request->post("tablename/a");
  52. if (in_array($do_action, array('doquery', 'optimizeall', 'repairall')))
  53. {
  54. AdminLog::record(__('query'), ['table' => $tablename, 'action' => $do_action, 'sql' => $this->request->post('sqlquery')]);
  55. $this->$do_action();
  56. }
  57. else if (count($tablename) == 0)
  58. {
  59. exit(__('Invalid parameters'));
  60. }
  61. else
  62. {
  63. AdminLog::record(__('query'), ['table' => $tablename, 'action' => $do_action]);
  64. foreach ($tablename as $table)
  65. {
  66. $this->$do_action($table);
  67. echo "<br />";
  68. }
  69. }
  70. }
  71. private function viewinfo($name)
  72. {
  73. $row = Db::query("SHOW CREATE TABLE `{$name}`");
  74. $row = array_values($row[0]);
  75. $info = $row[1];
  76. echo "<xmp>{$info};</xmp>";
  77. }
  78. private function viewdata($name = '')
  79. {
  80. $sqlquery = "SELECT * FROM `{$name}`";
  81. $this->doquery($sqlquery);
  82. }
  83. private function optimize($name = '')
  84. {
  85. if (Db::execute("OPTIMIZE TABLE `{$name}`"))
  86. {
  87. echo __('Optimize table %s done', $name);
  88. }
  89. else
  90. {
  91. echo __('Optimize table %s fail', $name);
  92. }
  93. }
  94. private function optimizeall($name = '')
  95. {
  96. $list = Db::query("SHOW TABLES");
  97. foreach ($list as $key => $row)
  98. {
  99. $name = reset($row);
  100. if (Db::execute("OPTIMIZE TABLE {$name}"))
  101. {
  102. echo __('Optimize table %s done', $name);
  103. }
  104. else
  105. {
  106. echo __('Optimize table %s fail', $name);
  107. }
  108. echo "<br />";
  109. }
  110. }
  111. private function repair($name = '')
  112. {
  113. if (Db::execute("REPAIR TABLE `{$name}`"))
  114. {
  115. echo __('Repair table %s done', $name);
  116. }
  117. else
  118. {
  119. echo __('Repair table %s fail', $name);
  120. }
  121. }
  122. private function repairall($name = '')
  123. {
  124. $list = Db::query("SHOW TABLES");
  125. foreach ($list as $key => $row)
  126. {
  127. $name = reset($row);
  128. if (Db::execute("REPAIR TABLE {$name}"))
  129. {
  130. echo __('Repair table %s done', $name);
  131. }
  132. else
  133. {
  134. echo __('Repair table %s fail', $name);
  135. }
  136. echo "<br />";
  137. }
  138. }
  139. private function doquery($sql = null)
  140. {
  141. $sqlquery = $sql ? $sql : $this->request->post('sqlquery');
  142. if ($sqlquery == '')
  143. exit(__('SQL can not be empty'));
  144. $sqlquery = str_replace("\r", "", $sqlquery);
  145. $sqls = preg_split("/;[ \t]{0,}\n/i", $sqlquery);
  146. $maxreturn = 100;
  147. $r = '';
  148. foreach ($sqls as $key => $val)
  149. {
  150. if (trim($val) == '')
  151. continue;
  152. $val = rtrim($val, ';');
  153. $r .= "SQL:<span style='color:green;'>{$val}</span> ";
  154. if (preg_match("/^(select|explain)(.*)/i ", $val))
  155. {
  156. Debug::remark("begin");
  157. $limit = stripos(strtolower($val), "limit") !== false ? true : false;
  158. $count = Db::execute($val);
  159. if ($count > 0)
  160. {
  161. $resultlist = Db::query($val . (!$limit && $count > $maxreturn ? ' LIMIT ' . $maxreturn : ''));
  162. }
  163. else
  164. {
  165. $resultlist = [];
  166. }
  167. Debug::remark("end");
  168. $time = Debug::getRangeTime('begin', 'end', 4);
  169. $usedseconds = __('Query took %s seconds', $time) . "<br />";
  170. if ($count <= 0)
  171. {
  172. $r .= __('Query returned an empty result');
  173. }
  174. else
  175. {
  176. $r .= (__('Total:%s', $count) . (!$limit && $count > $maxreturn ? ',' . __('Max output:%s', $maxreturn) : ""));
  177. }
  178. $r = $r . ',' . $usedseconds;
  179. $j = 0;
  180. foreach ($resultlist as $m => $n)
  181. {
  182. $j++;
  183. if (!$limit && $j > $maxreturn)
  184. break;
  185. $r .= "<hr/>";
  186. $r .= "<font color='red'>" . __('Row:%s', $j) . "</font><br />";
  187. foreach ($n as $k => $v)
  188. {
  189. $r .= "<font color='blue'>{$k}:</font>{$v}<br/>\r\n";
  190. }
  191. }
  192. }
  193. else
  194. {
  195. Debug::remark("begin");
  196. $count = Db::execute($val);
  197. Debug::remark("end");
  198. $time = Debug::getRangeTime('begin', 'end', 4);
  199. $r .= __('Query affected %s rows and took %s seconds', $count, $time) . "<br />";
  200. }
  201. }
  202. echo $r;
  203. }
  204. }