Web展示MySQL库表结构和字段定义的PHP小脚本

版权声明:本文为博主原创文章,转载敬请作出引用声明方便相互交流学习! https://blog.csdn.net/sweeper_freedoman/article/details/84405373

【!!!!改程序有尚未解决的分页BUG请忽略或自行修改BUG再使用!!!!】

MySQL数据库的库表结构和字段定义等元数据可以很方便地在`information_schema`系统库中查询到,但工作中一些非数据库岗位的同学很多都不了解这一点,经常会碰到过来询问某某数据存在哪张表的情况。如果能把数据库的表框架信息比较直观地展示出来,那就既方便了其他同学查询,也减轻了一些额外的“非战斗性”工作量。所以,就想着写一个Web页面吧,上网查了查资料,用PHP写了一个个人称作“Tableviewer”的小展示程序。

以下是相关的各个文件。

①config.php

<?php
/*
    * create_author : 蛙鳜鸡鹳狸猿
    * create_time   : 2018-11-20
    * program       : *_* web config *_*
*/


/* Website relevant */
$timezone="Asia/Shanghai";
header("Content-Type: text/html; charset=utf-8");

/* MySQL relevant */
$host="192.168.252.130";
$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
$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 : 蛙鳜鸡鹳狸猿
    * 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 : 蛙鳜鸡鹳狸猿
    * create_time   : 2018-11-20
    * program       : *_* web index *_*
*/


include_once("config.php");
require_once("page.php");
require_once("query.php");


?>


<!DOCTYPE html>
<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>
                <li><font size='8' color="black"><b>Tableviewer Service</b></font></li>
            </ul>
        </div>

        <div>
			<!--h2 class="title"><font size='3' color="black">ようこそ...</font></h2-->

			<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%; align:center; text-align:center">
							<form method="POST">
								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">
								<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

							if ($_SERVER['REQUEST_METHOD'] == 'POST'){
									$table = $_POST["table"];
									$table_schema = $_POST["table_schema"];
									$table_comment = $_POST["table_comment"];
									$table_column = $_POST["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://blog.csdn.net/sweeper_freedoman" target="_blank">https://blog.csdn.net/sweeper_freedoman</a>
        </div>

    </body>
</html>

该程序主要具有以下特性或者说设定吧:

  1. 数据取自MySQL系统库`information_schema`,每次查询都是实时数据,不存在数据层面的延迟和不准确;
  2. 每个栏目列都添加了筛选框,方便快速查询;
  3. 筛选框既支持单个栏目查询,也支持多个框任意组合查询;
  4. 筛选框的后台是纯SQL语句,并且使用REGEXP正则表达式命令匹配,查询功能更加强大;
  5. 具体的数据行以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

http://www.php.cn/css-tutorial-375461.html

https://blog.csdn.net/qq_36370731/article/details/78069056

猜你喜欢

转载自blog.csdn.net/sweeper_freedoman/article/details/84405373