MySQL数据库的库表结构和字段定义等元数据可以很方便地在`information_schema`系统库中查询到,但工作中一些非数据库岗位的同学很多都不了解这一点,经常会碰到过来询问某某数据存在哪张表的情况。如果能把数据库的表框架信息比较直观地展示出来,那就既方便了其他同学查询,也减轻了一些额外的“非战斗性”工作量。所以,就想着写一个Web页面吧,上网查了查资料,用PHP写了一个个人称作“Tableviewer”的小展示程序。
以下是相关的各个文件。
①config.php
<?php
/*
* create_author : Bilery Zoo(652645572@qq.com)
* create_time : 2018-11-20
* program : *_* web config *_*
*/
/* Website relevant */
$timezone="Asia/Shanghai";
header("Content-Type: text/html; charset=utf-8");
/* MySQL relevant */
$host="127.0.0.1";
$db_user="root";
$db_pass="1024";
$db_name="information_schema";
$conn = new mysqli($host, $db_user, $db_pass, $db_name);
/* Pagination relevant */
$curpage = empty($_GET['page']) ? 1 : $_GET['page']; //current page
$url = "?page={page}"; //pagination address
$query = $_GET;
unset($query["page"]);
foreach ($query as $key => $value) {
$url .= '&' .$key. '=' .$value;
}
$showrow = 10;
?>
②query.php
<?php
/*
* create_author : 蛙鳜鸡鹳狸猿
* create_time : 2018-11-22
* program : *_* SQL query *_*
*/
$sql = <<<QUERY
SELECT
t.`TABLE_NAME` AS `table_name`,
t.`TABLE_SCHEMA` AS `table_schema`,
t.`TABLE_COMMENT` AS `table_comment`,
GROUP_CONCAT(CONCAT(c.`COLUMN_NAME`, ': ', c.`COLUMN_TYPE`, '; ', c.`COLUMN_COMMENT`, CHAR(13)) SEPARATOR '') AS `table_column`
FROM `information_schema`.`TABLES` AS t
INNER JOIN `information_schema`.`COLUMNS` AS c
USING(`TABLE_NAME`)
WHERE 1 > 0
QUERY;
?>
③page.php
<?php
/*
* create_author : Bilery Zoo(652645572@qq.com)
* create_time : 2018-11-20
* program : *_* web pagination *_*
*/
class page {
private $myde_total; //total number rows counts
private $myde_size; //per-page show rows counts
private $myde_page; //current page number
private $myde_page_count; //total page counts
private $myde_i; //head page number
private $myde_en; //tail page number
private $myde_url; //current page url
private $show_pages;
public function __construct($myde_total = 1, $myde_size = 1, $myde_page = 1, $myde_url, $show_pages = 2) {
$this->myde_total = $this->numeric($myde_total);
$this->myde_size = $this->numeric($myde_size);
$this->myde_page = $this->numeric($myde_page);
$this->myde_page_count = ceil($this->myde_total / $this->myde_size);
$this->myde_url = $myde_url;
if ($this->myde_total < 0)
$this->myde_total = 0;
if ($this->myde_page < 1)
$this->myde_page = 1;
if ($this->myde_page_count < 1)
$this->myde_page_count = 1;
if ($this->myde_page > $this->myde_page_count)
$this->myde_page = $this->myde_page_count;
$this->limit = ($this->myde_page - 1) * $this->myde_size;
$this->myde_i = $this->myde_page - $show_pages;
$this->myde_en = $this->myde_page + $show_pages;
if ($this->myde_i < 1) {
$this->myde_en = $this->myde_en + (1 - $this->myde_i);
$this->myde_i = 1;
}
if ($this->myde_en > $this->myde_page_count) {
$this->myde_i = $this->myde_i - ($this->myde_en - $this->myde_page_count);
$this->myde_en = $this->myde_page_count;
}
if ($this->myde_i < 1)
$this->myde_i = 1;
}
/* digit diagnose */
private function numeric($num) {
if (strlen($num)) {
if (!preg_match("/^[0-9]+$/", $num)) {
$num = 1;
} else {
$num = substr($num, 0, 11);
}
} else {
$num = 1;
}
return $num;
}
/* address replace */
private function page_replace($page) {
return str_replace("{page}", $page, $this->myde_url);
}
/* head page */
private function myde_home() {
if ($this->myde_page != 1) {
return "<a href='" . $this->page_replace(1) . "' title='Head'>Head</a>";
} else {
return "<p>Head</p>";
}
}
/* last page */
private function myde_prev() {
if ($this->myde_page != 1) {
return "<a href='" . $this->page_replace($this->myde_page - 1) . "' title='last'>last</a>";
} else {
return "<p>last</p>";
}
}
/* next page */
private function myde_next() {
if ($this->myde_page != $this->myde_page_count) {
return "<a href='" . $this->page_replace($this->myde_page + 1) . "' title='next'>next</a>";
} else {
return"<p>next</p>";
}
}
/* tail page */
private function myde_last() {
if ($this->myde_page != $this->myde_page_count) {
return "<a href='" . $this->page_replace($this->myde_page_count) . "' title='Tail'>Tail</a>";
} else {
return "<p>Tail</p>";
}
}
/* out print */
public function myde_write($id = 'page') {
$str = "<div id=" . $id . ">";
$str.=$this->myde_home();
$str.=$this->myde_prev();
if ($this->myde_i > 1) {
$str.="<p class='pageEllipsis'>...</p>";
}
for ($i = $this->myde_i; $i <= $this->myde_en; $i++) {
if ($i == $this->myde_page) {
$str.="<a href='" . $this->page_replace($i) . "' title='The " . $i . " Page' class='cur'>$i</a>";
} else {
$str.="<a href='" . $this->page_replace($i) . "' title='The " . $i . " Page'>$i</a>";
}
}
if ($this->myde_en < $this->myde_page_count) {
$str.="<p class='pageEllipsis'>...</p>";
}
$str.=$this->myde_next();
$str.=$this->myde_last();
$str.="<p class='pageRemark'>Total <b>" . $this->myde_page_count .
"</b> Page <b>" . $this->myde_total . "</b> Data</p>";
$str.="</div>";
return $str;
}
}
?>
④index.css
/*
* create_author : 蛙鳜鸡鹳狸猿
* create_time : 2018-11-21
* program : *_* css decoration *_*
*/
*{
margin:0;
padding:0;
}
.container{
width: 100%;
font-size: 14px;
color: #000;
}
/* head */
.container>.header{
width: 100%;
height: 64px;
line-height: 64px;
font-size: 24px;
font-weight:bold;
padding-left: 20px;
}
.container>.title>h2{
width:100%;
height: 40px;
line-height: 40px;
font-size: 14px;
font-weight: bold;
padding-left: 20px;
}
/* form */
.search{
width: 100%;
height: 52px;
line-height: 52px;
font-size: 16px;
font-weight: bold;
padding-left: 20px;
}
.search>form>input{
width: 270px;
height: 30px;
border-radius: 5px;
outline: none;
}
.search>form>button{
width: 60px;
height: 33px;
border-radius: 5px;
line-height: 30px;
position: relative;
top: 2px;
outline: none;
}
/* table */
.gridtable{
width: 200%;
margin-top: 20px;
}
.gridtable>thead>tr>th{
min-width: 90px;
text-align: center;
}
.gridtable>tbody>tr>td{
min-width: 90px;
text-align: center;
}
p{margin:0}
#page{
height:40px;
padding:20px 0px;
}
#page a{
display:block;
float:left;
margin-right:10px;
padding:2px 12px;
height:24px;
border:1px #cccccc solid;
background:#fff;
text-decoration:none;
color:#808080;
font-size:12px;
line-height:24px;
}
#page a:hover{
color:#077ee3;
border:1px #077ee3 solid;
}
#page a.cur{
border:none;
background:#077ee3;
color:#fff;
}
#page p{
float:left;
padding:2px 12px;
font-size:12px;
height:24px;
line-height:24px;
color:#bbb;
border:1px #ccc solid;
background:#fcfcfc;
margin-right:8px;
}
#page p.pageRemark{
border-style:none;
background:none;
margin-right:0px;
padding:4px 0px;
color:#666;
}
#page p.pageRemark b{
color:black;
}
#page p.pageEllipsis{
border-style:none;
background:none;
padding:4px 0px;
color:#808080;
}
⑤index.php
<?php
/*
* create_author : Bilery Zoo(652645572@qq.com)
* create_time : 2018-11-20
* program : *_* web index *_*
*/
include_once("config.php");
require_once("page.php");
require_once("query.php");
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Welcome Tableviewer...</title>
<style type="text/css">
p{margin:0}
#page{
height:40px;
padding:20px 0px;
}
#page a{
display:block;
float:left;
margin-right:10px;
padding:2px 12px;
height:24px;
border:1px #cccccc solid;
background:#fff;
text-decoration:none;
color:#808080;
font-size:12px;
line-height:24px;
}
#page a:hover{
color:#077ee3;
border:1px #077ee3 solid;
}
#page a.cur{
border:none;
background:#077ee3;
color:#fff;
}
#page p{
float:left;
padding:2px 12px;
font-size:12px;
height:24px;
line-height:24px;
color:#bbb;
border:1px #ccc solid;
background:#fcfcfc;
margin-right:8px;
}
#page p.pageRemark{
border-style:none;
background:none;
margin-right:0px;
padding:4px 0px;
color:#666;
}
#page p.pageRemark b{
color:black;
}
#page p.pageEllipsis{
border-style:none;
background:none;
padding:4px 0px;
color:#808080;
}
</style>
</head>
<body>
<div>
<ul>
<font size='8' color="black"><b>Tableviewer Service</b></font>
</ul>
</div>
<div>
<div>
<ul>
<style type="text/css">
table.gridtable {
font-family: verdana,arial,sans-serif;
font-size: 11px;
color: #333333;
border: 1px solid black;
border-width: 1px;
border-color: #666666;
border-collapse: collapse;
table-layout: fixed;
width: 100%;
word-break: break-all;
word-wrap: break-word;
white-space: normal;
overflow: auto;
margin: auto;
}
table.gridtable th {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #dedede;
table-layout: fixed;
}
table.gridtable td {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #ffffff;
table-layout: fixed;
white-space: pre-line;
}
.search{
width: 100%;
height: 52px;
line-height: 52px;
font-size: 16px;
font-weight: bold;
padding-left: 20px;
}
.search>form>input{
width: 270px;
height: 30px;
border-radius: 5px;
outline: none;
}
.search>form>button{
width: 60px;
height: 33px;
border-radius: 5px;
line-height: 30px;
position: relative;
top: 2px;
}
</style>
<table id="CaseResult" class="gridtable" align="center">
<div class="search" style="width:100%; height:100px; align:center; text-align:center">
<form method="GET">
table: <input type="text" name="table">
table_schema: <input type="text" name="table_schema">
table_comment: <input type="text" name="table_comment">
table_column: <input type="text" name="table_column">
<br>
<button>Search</button>
</form>
</div>
<tr>
<th align="center" width="80"> table </th>
<th align="center" width="80"> table_schema </th>
<th align="left" width="240"> table_comment </th>
<th align="left" width="240"> table_column </th>
</tr>
<?php
$table = empty($_GET["table"]) ? '' : $_GET["table"];
$table_schema = empty($_GET["table_schema"]) ? '' : $_GET["table_schema"];
$table_comment = empty($_GET["table_comment"]) ? '' : $_GET["table_comment"];
$table_column = empty($_GET["table_column"]) ? '' : $_GET["table_column"];
if ($table != ''){
$sql .= " AND t.`TABLE_NAME` REGEXP '" . $table . "'";
}
if ($table_schema != ''){
$sql .= " AND t.`TABLE_SCHEMA` REGEXP '" . $table_schema . "'";
}
if ($table_comment != ''){
$sql .= " AND t.`TABLE_COMMENT` REGEXP '" . $table_comment . "'";
}
if ($table_column != ''){
$sql .= " AND c.`COLUMN_NAME` REGEXP '" .$table_column . "'";
}
$sql .= " GROUP BY t.`TABLE_NAME`, t.`TABLE_SCHEMA`, t.`TABLE_COMMENT` ORDER BY t.`TABLE_SCHEMA`";
$total = mysqli_num_rows(mysqli_query($conn, $sql)); //Get rows counts
$sql .= " LIMIT " . ($curpage - 1) * $showrow . ",$showrow;";
$query = mysqli_query($conn, $sql);
$data=mysqli_fetch_all($query);
foreach ($data as $row) {
?>
<tr>
<td align="center"><?php echo $row[0] ?></td>
<td align="center"><?php echo $row[1] ?></td>
<td align="left"><?php echo $row[2] ?></td>
<td align="left"><?php echo $row[3] ?></td>
</tr>
<?php
}
?>
</table>
</ul>
</div>
<div>
<?php
if (!empty($_GET['page']) && $total != 0 && $curpage > ceil($total / $showrow)){
$curpage = ceil($total / $showrow);
} //binding last pagination
if ($total > $showrow) {
$page = new page($total, $showrow, $curpage, $url, 2);
echo $page->myde_write();
} //starting first pagination
?>
</div>
</div>
<div>
Powered by Bilery Zoo <a href="https://github.com/Bilery-Zoo" target="_blank">https://github.com/Bilery-Zoo</a>
</div>
</body>
</html>
该程序主要具有以下特性或者说设定吧:
- 数据取自MySQL系统库`information_schema`,每次查询都是实时数据,不存在数据层面的延迟和不准确;
- 每个栏目列都添加了筛选框,方便快速查询;
- 筛选框既支持单个栏目查询,也支持多个框任意组合查询;
- 筛选框的后台是纯SQL语句,并且使用REGEXP正则表达式命令匹配,查询功能更加强大;
- 具体的数据行以MySQL表为维度,一张表一条数据,更加查阅友好化。
我个人是部署在本地的Ubuntu Linux虚拟机里的,下载安装了最新版的xampp-linux-x64-7.2.11-0,默认会安装到/opt/lampp,然后把以上文件放入该目录下的“htdocs”文件夹(需要替换或者备份替换一下同名文件),开启Apache服务,打开浏览器就OK了。因为自己一直做运维相关工作,根本没有多少Web相关的知识,在写脚本时查了很多资料,也让我程序媛的妹妹帮忙改了改(至少那个“index.css”文件是她写的),其中主要参考的文章如下。
https://blog.csdn.net/haibo0668/article/details/52448374
http://blog.51cto.com/babyhe/1118372