第一個目的是談論得最多的目的,它設想的情形是:一組程式員編寫用於產生頁面內容的PHP指令碼,同時另一組設計人員設計HTML和圖形以控制頁面的最終外觀。分離功能和布局的基本思想就是使得這兩組人能夠各自編寫和使用獨立的一組檔案:程式員只需關心那些只包含PHP代碼的檔案,無需關心頁面的外觀;而頁面設計人員可以用自己最熟悉的可視化編輯器設計頁面配置,無需擔心破壞任何嵌入到頁面的PHP代碼。
如果你曾經看過幾個關於PHP模板的教程,那麼你應該已經明白模板的工作機制。考慮一個簡單的頁面局部:頁面的上方是頁頭,左邊是導航條,其餘部分是內容地區。
可以看出頁面如何由模板構造而成:main模板控制著整個頁面的布局;header模板和leftnav模板控制著頁面的公用元素。花括弧“{}”裡面的標識符是內容預留位置。使用模板最主要的好處在於介面設計者能夠按照自己的意願編輯這些檔案,比如設定字型、修改顏色和圖形,或者完全地改變頁面的布局。介面設計者可以用任何普通HTML編輯器或者視覺化檢視編輯這些頁面,因為這些檔案都只包含HTML代碼,沒有任何PHP代碼。
PHP代碼全部儲存到單獨的檔案中,這個檔案也就是由頁面URL實際調用的檔案。Web伺服器通過PHP引擎解析該檔案,然後把結果返回給瀏覽器。一般地,PHP代碼總是動態地產生頁面內容,比如查詢資料庫或者執行某種計算等。下面是一個例子:
// 此處的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去正確地格式化最終頁面而擔心。
很容易看出採用模板還有第二個好處。如上例所示,頁面左邊的導航條單獨儲存為一個檔案,我們只需編輯這一個模板檔案就可以改變網站所有頁面左邊的導航條。
避免頁面元素重複
“這確實不錯”,你也許會想,“我的網站主要就是由大量的靜態頁面構成。現在我可以從所有頁面中刪除它們的公用部分,要更新這些公用部分實在太麻煩了。以後我就可以用模板製作出很容易維護的統一頁面配置。”但事情並非這麼簡單,“大量的靜態頁面”道出了問題的所在。
請考慮上面的例子。這個例子實際上只有一個example.php頁面,它之所以能夠產生整個網站的所有頁面,是因為它利用了URL中的查詢字串從資料庫之類的資訊源動態地構造出頁面。
我們之中的大多數人所啟動並執行網站並不一定都有資料庫支援。我們的網站大多數由靜態頁面構成,然後用PHP在這裡、那裡加上一些動態功能,比如搜尋引擎、反饋表單等。那麼,如何在這種網站上應用模板呢?
最簡單的方法是為每一個頁面複製一份PHP檔案,然後在每一個頁面中把PHP代碼裡代表內容的變數設定成合適的頁面內容。例如,假設有三個頁面,它們分別是首頁(home)、關於(about)和產品(product),我們可以用三個檔案分別產生它們。這三個檔案的內容都類如:
<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代碼。
靜態網站的模板架構:
ob_end_clean(); $tpl->assign('CONTENT', $content); $tpl->parse('HEADER', 'header'); $tpl->parse('LEFTNAV', 'leftnav'); $tpl->parse('MAIN', 'main'); $tpl->FastPrint('MAIN'); } ?>
ageStart函數首先建立並設定了一個模板執行個體,然後啟用輸出緩衝。此後,所有來自頁面本身的HTML內容都將進入緩衝。pageFinish函數取出緩衝中的內容,然後在模板對象中指定這些內容,最後解析模板並輸出完成後的頁面。
這就是整個模板架構全部的工作過程了。首先編寫包含了網站各個頁面公用元素的模板,然後從所有頁面中刪除全部公用的頁面配置代碼,代之以三行永遠無需改動的PHP代碼;再把FastTemplate類檔案和prepend.php加入到包含路徑,這樣你就得到了一個頁面配置可以集中控制的網站,它有著更好的可靠性和可維護性,而且網站級的大範圍修改也變得相當容易。