php造车轮:基于单主页+GET请求的模块化框架

上个学期修了一门软件工程课,我们小组的project是开发一个使用PHP的管理系统。只会 echo ‘Hello World’ 的我只好赶紧从校图书馆借了一本书《PHP 5 高级应用开发实践》来好好补充知识。书中提到了一个很有趣的模块化框架,实现起来也非常简单,用来新手入门练练手对网页结构的了解也是非常有益的。在这里把它分享出来给大家,也顺便回顾一下学到的知识。

在介绍框架之前,需要了解GET请求是什么。

GET请求

在用户与服务器之间进行请求-响应时,两种最常被用到的方法分别为:GETPOST

其中,GET请求的查询字符串是直接写在URL中进行发送的:

1
https://www.kavel.cn/?page=pdf

在这段URL中,?表示GET请求的开头,而page=pdf则是查询的键值对。

而GET请求也有如下的一些原则:

  • GET 请求可被缓存
  • GET 请求可保留在浏览器历史记录
  • GET 请求可被收藏为书签
  • GET 请求不应处理敏感数据时使用
  • GET 请求有长度限制
  • GET 请求只应当用于取回数据

在PHP中,我们使用$value=$_GET[$key]方法来获取GET的内容。
其中$key为我们自己定义的等号左边的内容(如page),称为
$value的内容即为我们需要获取的等号右边的内容(如pdf),称为

而这套框架的核心原理,则是利用了GET传递请求的可保留性,在单个页面(如index.php)通过GET请求获取到用户传来的不同的 ,并根据插入不同的模块页展现给用户。这是一种非常容易实现的模块化方案

话不多说,赶紧进入实战环节。

获取用户传来的GET信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*File name: index.php*/

//获取插入的子页面名称
if (isset($_GET['page'])) {
$p = sterilizeInput($_GET['page']);
} elseif (isset($_POST['page'])) {
$p = $_POST['page'];
} else {
$p = 'index';
}

//任何GET表单在赋值前必须使用消毒函数
function sterilizeInput($data) {
$data = trim($data); //移除字符串两侧的空白字符
$data = stripslashes($data); //移除字符串中的所有反斜杠
$data = htmlspecialchars($data); //将预定义的字符转换为 HTML 实体,可过滤单引号、双引号等
return $data;
}

我们应当提防用户能够通过GET请求上传恶意代码使得对网页进行的任意操作成为可能。所以在进行赋值前,使用消毒函数进行消毒非常重要。

根据GET信息选择要插入的模块页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*File name: index.php*/

//选择插入的子页面
switch ($p) {
case 'index':
$page = 'welcome.php';
$page_title = '主页';
break;
case 'pdf':
$page='pdf.php';
$page_title='课堂笔记';
break;
case 'resume':
$page='resume.html';
$page_title='简历';
break;
case '404':
header("HTTP/1.0 404 Not Found");
exit();
break;
default:
header("HTTP/1.0 404 Not Found");
exit();
break;
}

在这里,我们通过switch-case方式对得到的进行判断,得到对应的页面文件名称。还要记得如果对所有条件都不符合时,跳转到404页面。

插入模块页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*File name: index.php*/

//确保子页面存在
if (!file_exists('./modules/' . $page)) {
header("HTTP/1.0 404 Not Found");
exit();
}


//插入页眉文件
include_once('./includes/' . 'header.inc.html');

//插入子页面
include('./modules/' . $page);

//插入页脚文件
include_once('./includes/' . 'footer.inc.html');

使用include($page)函数进行页面的插入。在插入页面前,还需要判断该页面是否真实存在。如果不存在,记得跳转到404页面。

为了实现模块化,我将整个页面分成三部分,分别为页眉、正文和页脚。页眉负责页面的头文件、CSS等。通过插入相同的页眉文件,我们可以确保整个网站都能得到统一的风格。

使用模块化的框架可以极大地方便模板页的开发。因为这样直接省去了编写每个页面都相同且必须的头文件和CSS等项,直接从<body>部分开始下笔。 我在这里则更加极端(lǎn),模板页只负责一个<div>,其余内容都在页眉和页脚文件中。

这里是当page=index时,网页的组成内容:

1
2
3
4
5
6
7
8
9
10
/*File name: header.inc.html*/

<?php if (!isset($page_title)) $page_title='主页';?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title><?=$page_title?> - kavel.cn</title>
</head>
<body>
<div class="container body-content">

在页眉文件里,<title>标签里面的值$page_titleindex.php定义。使用这种模块化方式的好处之一,就是在index.php内定义的变量,可以当作全局变量,在所有模块页面都能任意使用。

1
2
3
4
5
6
7
8
9
10
11
/*File name: welcome.php*/

function randomSplash(){...}

<div class="jumbotron">
<div class="container">
<h1><?=randomSplash()?></h1>
<p>这里是嘉维小站,我是王嘉维。</p>
<p><a class="btn btn-primary btn-lg" href="/blog" role="button">进入博客</a></p>
</div>
</div>

可以看到在模块页面内只包含一个<div>。这极大地方便了模块页的开发,也不需要担心样式问题。

1
2
3
4
5
6
7
8
9
/*File name: footer.inc.html*/

</div>
<footer class="container body-content">
<hr />
<p>&copy; <?=date("Y",time())?> Jiawei W.</p>
</footer>
</body>
</html>

页尾文件则是包含各种结束标签。当然<footer>标签也存在于这里。

本站首页就是使用这种框架写成的,如果感兴趣的话可以点击链接参观:

https://www.kavel.cn/

为了把博客置顶,已经删除了这个页面了 –2018-08-03

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×