明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

用PHP制作靜態(tài)網(wǎng)站的模板框架

[摘要]模板能夠改善網(wǎng)站的結(jié)構(gòu)。本文闡述如何通過(guò)PHP 4的一個(gè)新功能和模板類,在由大量靜態(tài)HTML頁(yè)面構(gòu)成的網(wǎng)站中巧妙地運(yùn)用模板控制頁(yè)面布局。 提綱: =================================== 分離功能和布局 避免頁(yè)面元素重復(fù) 靜態(tài)網(wǎng)站的模板框架 =============...

模板能夠改善網(wǎng)站的結(jié)構(gòu)。本文闡述如何通過(guò)PHP 4的一個(gè)新功能和模板類,在由大量靜態(tài)HTML頁(yè)面構(gòu)成的網(wǎng)站中巧妙地運(yùn)用模板控制頁(yè)面布局。

提綱:

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

分離功能和布局


避免頁(yè)面元素重復(fù)


靜態(tài)網(wǎng)站的模板框架

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

分離功能和布局

首先我們來(lái)看看應(yīng)用模板的兩個(gè)主要目的:

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

避免頁(yè)面元素重復(fù)

第一個(gè)目的是談?wù)摰米疃嗟哪康,它設(shè)想的情形是:一組程序員編寫用于生成頁(yè)面內(nèi)容的PHP腳本,同時(shí)另一組設(shè)計(jì)人員設(shè)計(jì)HTML和圖形以控制頁(yè)面的最終外觀。分離功能和布局的基本思想就是使得這兩組人能夠各自編寫和使用獨(dú)立的一組文件:程序員只需關(guān)心那些只包含PHP代碼的文件,無(wú)需關(guān)心頁(yè)面的外觀;而頁(yè)面設(shè)計(jì)人員可以用自己最熟悉的可視化編輯器設(shè)計(jì)頁(yè)面布局,無(wú)需擔(dān)心破壞任何嵌入到頁(yè)面的PHP代碼。

如果你曾經(jīng)看過(guò)幾個(gè)關(guān)于PHP模板的教程,那么你應(yīng)該已經(jīng)明白模板的工作機(jī)制?紤]一個(gè)簡(jiǎn)單的頁(yè)面局部:頁(yè)面的上方是頁(yè)頭,左邊是導(dǎo)航條,其余部分是內(nèi)容區(qū)域。這種網(wǎng)站可以擁有如下模板文件:

<!-- 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="http://www.okasp.com/techinfo/sitelogo.jpg">

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

可以看出頁(yè)面如何由這些模板構(gòu)造而成:main模板控制著整個(gè)頁(yè)面的布局;header模板和leftnav模板控制著頁(yè)面的公共元素;ɡㄌ(hào)“{}”里面的標(biāo)識(shí)符是內(nèi)容占位符。使用模板最主要的好處在于界面設(shè)計(jì)者能夠按照自己的意愿編輯這些文件,比如設(shè)置字體、修改顏色和圖形,或者完全地改變頁(yè)面的布局。界面設(shè)計(jì)者可以用任何普通HTML編輯器或者可視化工具編輯這些頁(yè)面,因?yàn)檫@些文件都只包含HTML代碼,沒(méi)有任何PHP代碼。 PHP代碼全部保存到單獨(dú)的文件中,這個(gè)文件也就是由頁(yè)面URL實(shí)際調(diào)用的文件。Web服務(wù)器通過(guò)PHP引擎解析該文件,然后把結(jié)果返回給瀏覽器。一般地,PHP代碼總是動(dòng)態(tài)地生成頁(yè)面內(nèi)容,比如查詢數(shù)據(jù)庫(kù)或者執(zhí)行某種計(jì)算等。下面是一個(gè)例子:
<?php

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

// 此處的PHP代碼設(shè)置$content使其包含合適的頁(yè)面內(nèi)容

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

?>

這里我們使用的是流行的FastTemplate模板類,但其基本思路對(duì)于其他許多模板類來(lái)說(shuō)都一樣。首先你實(shí)例化一個(gè)類,告訴它到哪里去尋找模板文件以及哪一個(gè)模板文件與頁(yè)面的哪部分對(duì)應(yīng);接下來(lái)是生成頁(yè)面內(nèi)容,把結(jié)果賦予內(nèi)容的標(biāo)識(shí)符;然后,依次解析各個(gè)模板文件,模板類將執(zhí)行必要的替換操作;最后把解析結(jié)果輸出到瀏覽器。

這個(gè)文件完全由PHP代碼構(gòu)成,不包含任何HTML代碼,這是它最大的優(yōu)點(diǎn),F(xiàn)在,PHP程序員可以集中精力編寫生成頁(yè)面內(nèi)容的代碼,而不必為了如何生成HTML去正確地格式化最終頁(yè)面而擔(dān)心。

你可以使用這種方法和上面的文件構(gòu)造出一個(gè)完整的網(wǎng)站。如果PHP代碼是以URL中的查詢字符串為基礎(chǔ)生成頁(yè)面內(nèi)容,例如http://www.foo.com/example.php?article=099,你可以據(jù)此構(gòu)造出一個(gè)完整的雜志網(wǎng)站。

很容易看出采用模板還有第二個(gè)好處。如上例所示,頁(yè)面左邊的導(dǎo)航條單獨(dú)保存為一個(gè)文件,我們只需編輯這一個(gè)模板文件就可以改變網(wǎng)站所有頁(yè)面左邊的導(dǎo)航條。避免頁(yè)面元素重復(fù)
“這確實(shí)不錯(cuò)”,你也許會(huì)想,“我的網(wǎng)站主要就是由大量的靜態(tài)頁(yè)面構(gòu)成。現(xiàn)在我可以從所有頁(yè)面中刪除它們的公共部分,要更新這些公共部分實(shí)在太麻煩了。以后我就可以用模板制作出很容易維護(hù)的統(tǒng)一頁(yè)面布局!钡虑椴⒎沁@么簡(jiǎn)單,“大量的靜態(tài)頁(yè)面”道出了問(wèn)題的所在。

請(qǐng)考慮上面的例子。這個(gè)例子實(shí)際上只有一個(gè)example.php頁(yè)面,它之所以能夠生成整個(gè)網(wǎng)站的所有頁(yè)面,是因?yàn)樗昧薝RL中的查詢字符串從數(shù)據(jù)庫(kù)之類的信息源動(dòng)態(tài)地構(gòu)造出頁(yè)面。

我們之中的大多數(shù)人所運(yùn)行的網(wǎng)站并不一定都有數(shù)據(jù)庫(kù)支持。我們的網(wǎng)站大多數(shù)由靜態(tài)頁(yè)面構(gòu)成,然后用PHP在這里、那里加上一些動(dòng)態(tài)功能,比如搜索引擎、反饋表單等。那么,如何在這種網(wǎng)站上應(yīng)用模板呢?

最簡(jiǎn)單的方法是為每一個(gè)頁(yè)面復(fù)制一份PHP文件,然后在每一個(gè)頁(yè)面中把PHP代碼里代表內(nèi)容的變量設(shè)置成合適的頁(yè)面內(nèi)容。例如,假設(shè)有三個(gè)頁(yè)面,它們分別是主頁(yè)(home)、關(guān)于(about)和產(chǎn)品(product),我們可以用三個(gè)文件分別生成它們。這三個(gè)文件的內(nèi)容都類如:

<?php

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

$content = "<p>歡迎訪問(wèn)</p>
<img src=\"http://www.okasp.com/techinfo/demo.jpg\">
<p>希望你能夠喜歡本網(wǎng)站</p>";
$tpl->assign('CONTENT', $content);
$tpl->parse('HEADER', 'header');
$tpl->parse('LEFTNAV', 'leftnav');
$tpl->parse('MAIN', 'main');
$tpl->FastPrint('MAIN');

?>

顯然,這種方法有三個(gè)問(wèn)題:我們必須為每一個(gè)頁(yè)面復(fù)制這些復(fù)雜的、牽涉到模板的PHP代碼,這與重復(fù)公共頁(yè)面元素一樣使得頁(yè)面難以維護(hù);現(xiàn)在文件又混合了HTML和PHP代碼;為內(nèi)容變量賦值將變得非常困難,因?yàn)槲覀儽仨毺幚砗么罅康奶厥庾址?

解決這個(gè)問(wèn)題的關(guān)鍵就在于分離PHP代碼和HTML內(nèi)容,雖然我們不能從文件中刪除所有的HTML內(nèi)容,但可以移出絕大多數(shù)PHP代碼。靜態(tài)網(wǎng)站的模板框架

首先,我們象前面一樣為所有的頁(yè)面公用元素以及頁(yè)面整體布局編寫模板文件;然后從所有的頁(yè)面刪除公共部分,只留下頁(yè)面內(nèi)容;接下來(lái)再在每個(gè)頁(yè)面中加上三行PHP代碼,如下所示:

<?php

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

<h1>你好</h1>
<p>歡迎訪問(wèn)</p>
<img src="http://www.okasp.com/techinfo/demo.jpg">
<p>希望你能夠喜歡本網(wǎng)站</p>

<?php pageFinish(); ?>

?>

這種方法基本上解決了前面提到的各種問(wèn)題,F(xiàn)在文件里只有三行PHP代碼,而且沒(méi)有任何一行代碼直接涉及到模板,因此要改動(dòng)這些代碼的可能性極小。此外,由于HTML內(nèi)容位于PHP標(biāo)記之外,所以也不存在特殊字符的處理問(wèn)題。我們可以很容易地將這三行PHP代碼加入到所有靜態(tài)HTML頁(yè)面中。

require函數(shù)引入了一個(gè)PHP文件,這個(gè)文件包含了所有必需的與模板相關(guān)的PHP代碼。其中pageStart函數(shù)設(shè)置模板對(duì)象以及頁(yè)面標(biāo)題,pageFinish函數(shù)解析模板然后生成結(jié)果發(fā)送給瀏覽器。

這是如何實(shí)現(xiàn)的呢?為什么在調(diào)用pageFinish函數(shù)之前文件中的HTML不會(huì)發(fā)送給瀏覽器?答案就在于PHP 4的一個(gè)新功能,這個(gè)功能允許把輸出到瀏覽器的內(nèi)容截獲到緩沖區(qū)之中。讓我們來(lái)看看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函數(shù)首先創(chuàng)建并設(shè)置了一個(gè)模板實(shí)例,然后啟用輸出緩存。此后,所有來(lái)自頁(yè)面本身的HTML內(nèi)容都將進(jìn)入緩存。pageFinish函數(shù)取出緩存中的內(nèi)容,然后在模板對(duì)象中指定這些內(nèi)容,最后解析模板并輸出完成后的頁(yè)面。
這就是整個(gè)模板框架全部的工作過(guò)程了。首先編寫包含了網(wǎng)站各個(gè)頁(yè)面公共元素的模板,然后從所有頁(yè)面中刪除全部公共的頁(yè)面布局代碼,代之以三行永遠(yuǎn)無(wú)需改動(dòng)的PHP代碼;再把FastTemplate類文件和prepend.php加入到包含路徑,這樣你就得到了一個(gè)頁(yè)面布局可以集中控制的網(wǎng)站,它有著更好的可靠性和可維護(hù)性,而且網(wǎng)站級(jí)的大范圍修改也變得相當(dāng)容易。

本文下載包包含了一個(gè)可運(yùn)行的示例網(wǎng)站,它的代碼注釋要比前面的代碼注釋更詳細(xì)一些。FastTemplate類可以在http://www.thewebmasters.net/找到,最新的版本號(hào)是1.1.0,那里還有一個(gè)用于保證該類在PHP 4中正確運(yùn)行的小補(bǔ)丁。本文下載代碼中的類已經(jīng)經(jīng)過(guò)該補(bǔ)丁的修正。