用PHP制作静态网站的模板框架


Posted in PHP onOctober 09, 2006

模板能够改善网站的结构。本文阐述如何通过PHP 4的一个新功能和模板类,在由大量静态HTML页面构成的网站中巧妙地运用模板控制页面布局。

提纲:

===================================

分离功能和布局

避免页面元素重复

静态网站的模板框架

===================================

分离功能和布局

首先我们来看看应用模板的两个主要目的:

分离功能(PHP)和布局(HTML)

避免页面元素重复

第一个目的是谈论得最多的目的,它设想的情形是:一组程序员编写用于生成页面内容的PHP脚本,同时另一组设计人员设计HTML和图形以控制页面的最终外观。分离功能和布局的基本思想就是使得这两组人能够各自编写和使用独立的一组文件:程序员只需关心那些只包含PHP代码的文件,无需关心页面的外观;而页面设计人员可以用自己最熟悉的可视化编辑器设计页面布局,无需担心破坏任何嵌入到页面的PHP代码。

如果你曾经看过几个关于PHP模板的教程,那么你应该已经明白模板的工作机制。考虑一个简单的页面局部:页面的上方是页头,左边是导航条,其余部分是内容区域。这种网站可以拥有如下模板文件:

<!-- main.htm -->
<html>
<head><title>模板示例</title></head>
<body>
<table><tr><td>{HEADER}</td></tr>
<tr><td>{LEFTNAV}</td><td>{CONTENT}</td></tr>
</table>
</body></html>

<!-- header.htm -->
<img src="sitelogo.jpg">

<!-- leftnav.htm -->
<br><a href="foo">Foo</a>
<br><a href="bar">Bar</a>

可以看出页面如何由这些模板构造而成:main模板控制着整个页面的布局;header模板和leftnav模板控制着页面的公共元素。花括号“{}”里面的标识符是内容占位符。使用模板最主要的好处在于界面设计者能够按照自己的意愿编辑这些文件,比如设置字体、修改颜色和图形,或者完全地改变页面的布局。界面设计者可以用任何普通HTML编辑器或者可视化工具编辑这些页面,因为这些文件都只包含HTML代码,没有任何PHP代码。 PHP代码全部保存到单独的文件中,这个文件也就是由页面URL实际调用的文件。Web服务器通过PHP引擎解析该文件,然后把结果返回给浏览器。一般地,PHP代码总是动态地生成页面内容,比如查询数据库或者执行某种计算等。下面是一个例子:
<?php

// example.php
require('class.FastTemplate.php');
$tpl = new FastTemplate('.');
$tpl->define( array( 'main' => 'main.htm',
'header' => 'header.htm',
'leftnav' => 'leftnav.htm' ) );

// 此处的PHP代码设置$content使其包含合适的页面内容

$tpl->assign('CONTENT', $content);
$tpl->parse('HEADER', 'header');
$tpl->parse('LEFTNAV', 'leftnav');
$tpl->parse('MAIN', 'main');
$tpl->FastPrint('MAIN');

?>

这里我们使用的是流行的FastTemplate模板类,但其基本思路对于其他许多模板类来说都一样。首先你实例化一个类,告诉它到哪里去寻找模板文件以及哪一个模板文件与页面的哪部分对应;接下来是生成页面内容,把结果赋予内容的标识符;然后,依次解析各个模板文件,模板类将执行必要的替换操作;最后把解析结果输出到浏览器。

这个文件完全由PHP代码构成,不包含任何HTML代码,这是它最大的优点。现在,PHP程序员可以集中精力编写生成页面内容的代码,而不必为了如何生成HTML去正确地格式化最终页面而担心。

你可以使用这种方法和上面的文件构造出一个完整的网站。如果PHP代码是以URL中的查询字符串为基础生成页面内容,例如http://www.foo.com/example.php?article=099,你可以据此构造出一个完整的杂志网站。

很容易看出采用模板还有第二个好处。如上例所示,页面左边的导航条单独保存为一个文件,我们只需编辑这一个模板文件就可以改变网站所有页面左边的导航条。 避免页面元素重复
“这确实不错”,你也许会想,“我的网站主要就是由大量的静态页面构成。现在我可以从所有页面中删除它们的公共部分,要更新这些公共部分实在太麻烦了。以后我就可以用模板制作出很容易维护的统一页面布局。”但事情并非这么简单,“大量的静态页面”道出了问题的所在。

请考虑上面的例子。这个例子实际上只有一个example.php页面,它之所以能够生成整个网站的所有页面,是因为它利用了URL中的查询字符串从数据库之类的信息源动态地构造出页面。

我们之中的大多数人所运行的网站并不一定都有数据库支持。我们的网站大多数由静态页面构成,然后用PHP在这里、那里加上一些动态功能,比如搜索引擎、反馈表单等。那么,如何在这种网站上应用模板呢?

最简单的方法是为每一个页面复制一份PHP文件,然后在每一个页面中把PHP代码里代表内容的变量设置成合适的页面内容。例如,假设有三个页面,它们分别是主页(home)、关于(about)和产品(product),我们可以用三个文件分别生成它们。这三个文件的内容都类如:

<?php

// home.php
require('class.FastTemplate.php');
$tpl = new FastTemplate('.');
$tpl->define( array( 'main' => 'main.htm',
'header' => 'header.htm',
'leftnav' => 'leftnav.htm' ) );

$content = "<p>欢迎访问</p>
<img src=\"demo.jpg\">
<p>希望你能够喜欢本网站</p>";
$tpl->assign('CONTENT', $content);
$tpl->parse('HEADER', 'header');
$tpl->parse('LEFTNAV', 'leftnav');
$tpl->parse('MAIN', 'main');
$tpl->FastPrint('MAIN');

?>

显然,这种方法有三个问题:我们必须为每一个页面复制这些复杂的、牵涉到模板的PHP代码,这与重复公共页面元素一样使得页面难以维护;现在文件又混合了HTML和PHP代码;为内容变量赋值将变得非常困难,因为我们必须处理好大量的特殊字符。

解决这个问题的关键就在于分离PHP代码和HTML内容,虽然我们不能从文件中删除所有的HTML内容,但可以移出绝大多数PHP代码。 静态网站的模板框架

首先,我们象前面一样为所有的页面公用元素以及页面整体布局编写模板文件;然后从所有的页面删除公共部分,只留下页面内容;接下来再在每个页面中加上三行PHP代码,如下所示:

<?php

<!-- home.php -->
<?php require('prepend.php'); ?>
<?php pageStart('Home'); ?>

<h1>你好</h1>
<p>欢迎访问</p>
<img src="demo.jpg">
<p>希望你能够喜欢本网站</p>

<?php pageFinish(); ?>

?>

这种方法基本上解决了前面提到的各种问题。现在文件里只有三行PHP代码,而且没有任何一行代码直接涉及到模板,因此要改动这些代码的可能性极小。此外,由于HTML内容位于PHP标记之外,所以也不存在特殊字符的处理问题。我们可以很容易地将这三行PHP代码加入到所有静态HTML页面中。

require函数引入了一个PHP文件,这个文件包含了所有必需的与模板相关的PHP代码。其中pageStart函数设置模板对象以及页面标题,pageFinish函数解析模板然后生成结果发送给浏览器。

这是如何实现的呢?为什么在调用pageFinish函数之前文件中的HTML不会发送给浏览器?答案就在于PHP 4的一个新功能,这个功能允许把输出到浏览器的内容截获到缓冲区之中。让我们来看看prepend.php的具体代码:

<?php

require('class.FastTemplate.php');

function pageStart($title = '') {
GLOBAL $tpl;
$tpl = new FastTemplate('.');
$tpl->define( array( 'main' => 'main.htm',
'header' => 'header.htm',
'leftnav'=> 'leftnav.htm' ) );
$tpl->assign('TITLE', $title);
ob_start();
}

function pageFinish() {
GLOBAL $tpl;
$content = ob_get_contents();
ob_end_clean();
$tpl->assign('CONTENT', $content);
$tpl->parse('HEADER', 'header');
$tpl->parse('LEFTNAV', 'leftnav');
$tpl->parse('MAIN', 'main');
$tpl->FastPrint('MAIN');
}

?> pageStart函数首先创建并设置了一个模板实例,然后启用输出缓存。此后,所有来自页面本身的HTML内容都将进入缓存。pageFinish函数取出缓存中的内容,然后在模板对象中指定这些内容,最后解析模板并输出完成后的页面。

用PHP制作静态网站的模板框架

这就是整个模板框架全部的工作过程了。首先编写包含了网站各个页面公共元素的模板,然后从所有页面中删除全部公共的页面布局代码,代之以三行永远无需改动的PHP代码;再把FastTemplate类文件和prepend.php加入到包含路径,这样你就得到了一个页面布局可以集中控制的网站,它有着更好的可靠性和可维护性,而且网站级的大范围修改也变得相当容易。

本文下载包包含了一个可运行的示例网站,它的代码注释要比前面的代码注释更详细一些。FastTemplate类可以在http://www.thewebmasters.net/找到,最新的版本号是1.1.0,那里还有一个用于保证该类在PHP 4中正确运行的小补丁。本文下载代码中的类已经经过该补丁的修正。

PHP 相关文章推荐
phpMyAdmin 安装及问题总结
May 28 PHP
PHP isset()与empty()的使用区别详解
Aug 29 PHP
完美解决:Apache启动问题―(OS 10022)提供了一个无效的参数
Jun 08 PHP
PHP实现把数字ID转字母ID
Aug 12 PHP
php生成图形验证码几种方法小结
Aug 15 PHP
让ThinkPHP支持大小写url地址访问的方法
Oct 31 PHP
php生成rss类用法实例
Apr 14 PHP
PHP精确计算功能示例
Nov 29 PHP
PHP生成二维码与识别二维码的方法详解【附源码下载】
Mar 07 PHP
YII2.0框架行为(Behavior)深入详解
Jul 26 PHP
php中文语义分析实现方法示例
Sep 28 PHP
laravel返回统一格式错误码问题
Nov 04 PHP
PHP5在Apache下的两种模式的安装
Sep 05 #PHP
WINDOWS 2000下使用ISAPI方式安装PHP
Sep 05 #PHP
教你IIS6的PHP最佳配置方法
Sep 05 #PHP
详细介绍:Apache+PHP+MySQL配置攻略
Sep 05 #PHP
PHP环境搭建最新方法
Sep 05 #PHP
初学者入门:细述PHP4的核心Zend
Sep 05 #PHP
PHP在XP下IIS和Apache2服务器上的安装
Sep 05 #PHP
You might like
为查询结果建立向后/向前按钮
2006/10/09 PHP
PHP中使用crypt()实现用户身份验证的代码
2012/09/05 PHP
ThinkPHP的cookie和session冲突造成Cookie不能使用的解决方法
2014/07/01 PHP
深入解析PHP中SESSION反序列化机制
2017/03/01 PHP
jquery 插件开发方法小结
2009/10/23 Javascript
GWT中复制到剪贴板 js+flash实现复制 兼容性比较好
2010/03/07 Javascript
js确认删除对话框适用于a标签及submit
2014/07/10 Javascript
字段太多jquey快速清空表单内容方法
2014/08/21 Javascript
webuploader模态框ueditor显示问题解决方法
2016/12/27 Javascript
微信小程序引用公共js里的方法的实例详解
2017/08/17 Javascript
express如何使用session与cookie的方法
2018/01/30 Javascript
详解Vue微信授权登录前后端分离较为优雅的解决方案
2018/06/29 Javascript
JS实现带阴历的日历功能详解
2019/01/24 Javascript
JS匿名函数内部this指向问题详析
2019/05/10 Javascript
Vue+Typescript中在Vue上挂载axios使用时报错问题
2019/08/07 Javascript
[01:14:05]《加油DOTA》第四期
2014/08/25 DOTA
[40:03]RNG vs VG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
极简的Python入门指引
2015/04/01 Python
Python中join和split用法实例
2015/04/14 Python
让python 3支持mysqldb的解决方法
2017/02/14 Python
Python利用openpyxl库遍历Sheet的实例
2018/05/03 Python
Python中pandas dataframe删除一行或一列:drop函数详解
2018/07/03 Python
python 移除字符串尾部的数字方法
2018/07/17 Python
详解Python的三种可变参数
2019/05/08 Python
python实现爬取百度图片的方法示例
2019/07/06 Python
Pytorch卷积层手动初始化权值的实例
2019/08/17 Python
python支付宝支付示例详解
2019/08/22 Python
python 实现多线程下载m3u8格式视频并使用fmmpeg合并
2019/11/15 Python
利用pytorch实现对CIFAR-10数据集的分类
2020/01/14 Python
使用TFRecord存取多个数据案例
2020/02/17 Python
天网面试题
2013/04/07 面试题
应届护士求职信范文
2014/01/26 职场文书
推荐信格式范文
2014/05/09 职场文书
模特大赛策划方案
2014/05/28 职场文书
注册资产评估专业求职信
2014/07/16 职场文书
Redis 常见使用场景
2021/08/30 Redis