用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 相关文章推荐
PHP Stream_*系列函数
Aug 01 PHP
利用php绘制饼状图的实现代码
Jun 07 PHP
探讨php中遍历二维数组的几种方法详解
Jun 08 PHP
android上传图片到PHP的过程详解
Aug 03 PHP
php视频拍照上传头像功能实现代码分享
Oct 08 PHP
高质量PHP代码的50个实用技巧必备(下)
Jan 22 PHP
php简单压缩css样式示例
Sep 22 PHP
php基于websocket搭建简易聊天室实践
Oct 24 PHP
php使用正则表达式获取字符串中的URL
Dec 29 PHP
ThinkPHP中create()方法自动验证实例
Apr 26 PHP
浅谈PHP发送HTTP请求的几种方式
Jul 25 PHP
php实现微信企业付款到个人零钱功能
Oct 09 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
php中in_array函数用法探究
2014/11/25 PHP
PHP 实现人民币小写转换成大写的方法及大小写转换函数
2017/11/17 PHP
小议javascript 设计模式 推荐
2009/10/28 Javascript
20个非常棒的 jQuery 幻灯片插件和教程分享
2011/08/23 Javascript
JQuery插件Style定制化方法的分析与比较
2012/05/03 Javascript
js的Prototype属性解释及常用方法
2014/05/08 Javascript
jQuery验证元素是否为空的两种常用方法
2015/03/17 Javascript
js模拟淘宝网的多级选择菜单实现方法
2015/08/18 Javascript
javascript中checkbox使用方法实例演示
2015/11/19 Javascript
JS中多步骤多分步的StepJump组件实例详解
2016/04/01 Javascript
Bootstrap Chart组件使用教程
2016/04/28 Javascript
jquery实现上传文件大小类型的验证例子(推荐)
2016/06/25 Javascript
Angular在一个页面中使用两个ng-app的方法
2017/02/20 Javascript
Bootstrap实现基于carousel.js框架的轮播图效果
2017/05/02 Javascript
一步步教你利用webpack如何搭一个vue脚手架(超详细讲解和注释)
2018/01/08 Javascript
spirngmvc js传递复杂json参数到controller的实例
2018/03/29 Javascript
js函数柯里化的方法和作用实例分析
2020/04/11 Javascript
vue项目接口管理,所有接口都在apis文件夹中统一管理操作
2020/08/13 Javascript
[02:12]打造更好的电竞完美世界:完美盛典回顾篇
2018/12/19 DOTA
在Python的Flask框架中实现全文搜索功能
2015/04/20 Python
视觉直观感受若干常用排序算法
2017/04/13 Python
python skimage 连通性区域检测方法
2018/06/21 Python
用Python shell简化开发
2018/08/08 Python
使用python实现语音文件的特征提取方法
2019/01/09 Python
python脚本之一键移动自定格式文件方法实例
2019/09/02 Python
解决Tensorflow sess.run导致的内存溢出问题
2020/02/05 Python
澳大利亚宠物食品和药物在线:Jumbo Pets
2018/03/24 全球购物
北京-环亚运商测试题.net程序员初步测试题
2013/05/28 面试题
javascript实现用户必须勾选协议实例讲解
2021/03/24 Javascript
人力资源专员岗位职责
2014/01/30 职场文书
小班秋游活动方案
2014/02/22 职场文书
运动会报道稿300字
2014/10/02 职场文书
三好学生个人总结
2015/02/15 职场文书
2015年远程教育工作总结
2015/05/20 职场文书
签证扫盲贴,41个常见签证知识,需要的拿走
2019/08/09 职场文书
Java服务调用RestTemplate与HttpClient的使用详解
2022/06/21 Java/Android