中文字幕二区_国产精品免费在线观看_黄色网站观看_人人草人人澡_日本真实娇小xxxx

您的位置: 首頁 > 技術(shù)文檔 > 網(wǎng)絡(luò)編程 > [PHP]超越模板引擎
[php]一次編寫,隨處運行 回到列表 PHP4之真OO
 [PHP]超越模板引擎

作者:陶文 時間: 2004-02-06 文檔類型:翻譯 來自:CSDN

作者:Brian Lozier

譯者:taowen

In general, template engines are a "good thing."
總體來說,模板引擎是一個"好東西"
  作為一個PHP/Perl的程序員,許多模板引擎(fastTemplate, Smarty, Perl的 HTML::Template)的用戶,以及我自己的bTemplate [1]的作者,我講這句話很多次了。
  然而,在同事進行了長時間的討論之后,我確信了大量的模板引擎(包括我自己寫的)根本是錯誤的。 我想唯一的例外是Smarty [2],雖然我認為它太龐大了,并且考慮到這篇文章的其余部分相當?shù)臎]有觀點。然而,就你為什么選擇Smarty(或者類似的解決方案)有幾個理由,這些將在文章后面探究。
  這篇文章討論模板的理論。我們將看到為什么大部分"模板引擎"是過于肥大,并且最終我們將回過頭來看一個輕量級的,小巧快速的另類選擇。
下載和授權(quán)
  模板類和所有在本文中使用的例子能夠在這里下載:template.zip [3]。你可以根據(jù)發(fā)布 [4]在OSI [5]的MIT Open Source License使用這些文件中的代碼。
一些關(guān)于模板引擎的背景知識
  讓我們首先研究一下模板引擎的背景知識。模板引擎被設(shè)計出來用于把商業(yè)邏輯(例如從數(shù)據(jù)庫中獲取數(shù)據(jù)或者計算貿(mào)易耗費)從數(shù)據(jù)的表現(xiàn)分離開來。模板引擎解決了兩個主要問題:

  1. 如何實現(xiàn)這種分離
  2. 如何從HTML中分離"復(fù)雜"的php代碼
  這從理論上使得沒有PHP經(jīng)驗的HTML設(shè)計者能夠不看任何PHP代碼的條件下修改站點的外觀。
  然而,模板系統(tǒng)也引入了一些復(fù)雜性。首先,我們現(xiàn)在有一個從多個文件得來的"頁面"。典型的,你可能有一個主PHP頁負責業(yè)務(wù)邏輯,一個外面的"布局"模板把整個站點的整體布局進行渲染,一個內(nèi)部的內(nèi)容特定的模板,一個數(shù)據(jù)庫抽象層,以及模板引擎本身(這些可能是也可能不是由多個文件組成)。也有可能,一些人僅僅簡單地在每個PHP頁面的首尾處包含"頭部"和"尾部"文件。
  這產(chǎn)生的單個頁面的文件數(shù)量是很可觀的。然而,因為PHP解析器非?,用到的文件數(shù)量可能不是那么重要除非你的站點流量很大。
  然而,要記住模板系統(tǒng)引入了另外一個處理的層次。模板文件不僅僅是必須被包含,他們還必須被解析(取決于模板系統(tǒng),這個行為有很多種方式來完成 —— 使用正則表達式,字符串替換,編譯,詞法分析,等等)。這就是為什么對模板進行測速變得流行起來:因為模板引擎使用各種方法來解析數(shù)據(jù),它們中的一些比另外一些要快(而且,一些模板引擎提供了比其他引擎更加豐富的功能)。
模板引擎基礎(chǔ)知識
  簡單地說,模板引擎利用了用C寫的腳本語言(PHP)。在這些嵌入的腳本語言中,你有另外一個偽腳本語言(無論你的模板引擎支持何種標簽)。某些提供了簡單的變量改寫和循環(huán)。另外一些呢,則提供了條件和嵌套循環(huán)。而再其他的呢(至少有Smarty)提供了一個PHP的比較大的子集的接口,以及一個緩沖層。
  為什么我認為Smarty最接近于正確的方向?因為Smarty的目標是"把業(yè)務(wù)邏輯從表現(xiàn)中分離出來"而不是"PHP代碼和HTML代碼的分離"。這看上去區(qū)別不大,但是它正是要點所在。任何模板引擎的最終目標不應(yīng)該是從HTML移除所有的邏輯。它應(yīng)該是把表現(xiàn)邏輯從業(yè)務(wù)邏輯中分離出來。
  有很多你僅僅需要邏輯來正確顯示你的數(shù)據(jù)的例子。例如,你的業(yè)務(wù)邏輯是從你的數(shù)據(jù)庫中獲取一個用戶列表。你的表現(xiàn)邏輯可能是把用戶列表用3列顯示?赡苄薷挠脩袅斜砗瘮(shù)使得它返回3個數(shù)組是很笨的辦法。畢竟函數(shù)不應(yīng)該關(guān)心數(shù)據(jù)接下來要怎么處理這樣的事情。然而,在你的模板文件中缺少一些邏輯,那些正是你要做的事情。
  在這點上Smarty是正確的(使得你利用PHP的很多東西),但是仍然有許多問題;旧希鼉H僅提供了一個以新語法訪問PHP的接口。以那開始,它看上去不那么聰明了。是不是事實上寫 {foreach --args}<? foreach --args ?> 更加簡單?如果你認為這樣簡單一些,問問你自己是不是在包含一個巨大的模板庫來到成這種分離時能夠看到真正的意義要更加簡單一些。誠然,Smarty提供了許多其他很好的特性,但是看上去這些益處能夠在不用承擔包含Smarty類庫的情況下也能獲得。
別樣的解決方案
  我主要要鼓吹的一個解決方案是一個使用PHP代碼作為它的原生腳本語言的"模板引擎"。我知道這以前有人做過。而且當我第一次看到的時候,我想,"為什么要這樣做?",然而我在考慮過我同事的論據(jù)之后,并且實現(xiàn)了一個直接使用PHP代碼仍然實現(xiàn)了把業(yè)務(wù)邏輯和表現(xiàn)邏輯分離的最終目標的模板系統(tǒng)時(只用了大約25行代碼,不包括注釋),我意識到了好處所在。
  這個系統(tǒng)給像我們這樣的開發(fā)者提供了對PHP核心函數(shù)的訪問權(quán)利,我們能夠使用他們來格式化輸出——像日期格式化這樣的任務(wù)應(yīng)該在模板中處理。而且,因為模板是普通的PHP文件,像Zend Performance Suite [6]和PHP Accelerator [7]這樣的字節(jié)碼緩存程序,能夠自動緩存模板(因而,它們不需要在每次被訪問時都被重新解釋執(zhí)行)。只要你記得把你的模板文件命名為程序能夠辨認出是PHP文件的名字(通常,你僅僅需要確保它們有一個.php的后綴),這確實是一個好處。
  當我認為這種方法比經(jīng)典的模板引擎要高明得多時,肯定還有一些要商榷的問題。最明顯的反面意見是,PHP代碼太復(fù)雜了,而且設(shè)計者不應(yīng)該強迫去學(xué)習(xí)PHP。事實上,PHP代碼和像Smarty這樣的高級模板引擎的語法差不多簡單(如果不是更簡單的話)。而且,設(shè)計者能夠使用像<?=$var;?>這樣的簡寫PHP。這要比{$var}復(fù)雜很多?當然,這要長一些,但是如果你習(xí)慣了,你能夠獲得了PHP的威力而且不用承受解析模板文件帶來的負擔。
  第二,而且可能更重要的,在基于PHP的模板中沒有固有的安全。Smarty提供了選項在模板文件中徹底禁用PHP代碼。它使得開發(fā)者能夠約束模板能夠訪問的函數(shù)和變量。如果你沒有不懷好意的設(shè)計者,這不會是什么問題。然而,如果你允許外部的用戶上傳或者修改模板,我在此展示的基于PHP的解決方案絕對沒有任何安全可言!任何代碼都能放入模板中并且得到運行。是的,甚至是一個print_r($GLOBALS)(這將改有惡意的用戶訪問腳本中任何變量的權(quán)利)。
  但是,我個人或者工作上寫過的項目中,絕大多數(shù)不允許最終的用戶修改或者上傳模板。如果是這樣,問題就不存在了。因此現(xiàn)在讓我們來看看代碼吧。
例子
這是一個簡單的用戶列表頁面的例子。
<?php
require_once('template.php');  

/**  
* This variable holds the file system path to all our template files.  
*/  
$path = './templates/';  

/**  
* Create a template object for the outer template and set its variables.  
*/  
$tpl = & new Template($path);  
$tpl->set('title', 'User List');  

/**  
* Create a template object for the inner template and set its variables.  The  
* fetch_user_list() function simply returns an array of users.  
*/  
$body = & new Template($path);  
$body->set('user_list', fetch_user_list());  

/**  
* Set the fetched template of the inner template to the 'body' variable in  
* the outer template.  
*/  
$tpl->set('body', $body->fetch('user_list.tpl.php'));  

/**  
* Echo the results.  
*/  
echo $tpl->fetch('index.tpl.php');  
?>
  其中有兩個值得注意的重要的概念。第一個就是內(nèi)部和外部模板的概念。外部模板包含定義站點主要外觀的HTML代碼。而內(nèi)部模板包含定義站點內(nèi)容區(qū)域的HTML代碼。當然,你能夠在任意數(shù)目的層上有任意數(shù)目的模板。因為通常我們給每個區(qū)域使用不同的模板對象,所以沒有名字空間的問題。例如,我能在內(nèi)部和外部模板中都有變量叫"title",而不用害怕有什么沖突。
  這是一個用來顯示用戶列表的模板的簡單例子。注意特殊的foreach和endforeach;語法在PHP手冊中有說明 [8]。它完全是可選擇的。
  而且,你可能奇怪我為什么要用.php的后綴來命名我的模板文件。呵呵,許多PHP字節(jié)碼緩存解決方案(比如 phpAccelerator)如果要被認成PHP文件,需要文件有一個.php后綴。因為這些模板是PHP文件,為什么不去獲得這些好處?
<table>  
   <tr>  
       <th>Id</th>  
       <th>Name</th>  
       <th>Email</th>  
       <th>Banned</th>  
   </tr>  
<? foreach($user_list as $user): ?>  
   <tr>  
       <td align="center"><?=$user['id'];?></td>  
       <td><?=$user['name'];?></td>  
       <td><a href="mailto:<?=$user['email'];?>"><?=$user['email'];?></a></td>  
       <td align="center"><?=($user['banned'] ? 'X' : '&nbsp;');?></td>  
   </tr>  
<? endforeach; ?>  
</table>


  這個layout.tpl.php是一個簡單的例子(定義了整個頁面看上去是什么樣子的模板文件)
<html>
   <head>
       <title><?=$title;?></title>
   </head> 
   <body> 
       <h2><?=$title;?></h2>
<?=$body;?> 
   </body>
</html>

And here's the parsed output.
而這是解析后的輸出。
代碼拷貝框

[Ctrl+A 全部選擇 然后拷貝]
Caching
緩存
  因為解決方案簡單如斯,實現(xiàn)模板緩存成為了一個非常簡單的任務(wù)。為了實現(xiàn)緩存,我們有一個二級類,它擴展了原來的模板類。CachedTemplate類事實上使用和原來的模板類相同的API。不同點是我們必須傳遞緩存的設(shè)置給構(gòu)造函數(shù),并且調(diào)用fetch_cache()而不是fetch()
  緩存的概念是簡單的。簡單的說,我們設(shè)置一個緩存時間來調(diào)表輸出應(yīng)該被保存的時長(以秒為單位)。在產(chǎn)生一個頁面的所有工作開展之前,我們必須首先測試頁面是否已經(jīng)被緩存了,而且緩存是否仍然沒有過期。如果緩存在這那,我們不需要在去麻煩數(shù)據(jù)庫和業(yè)務(wù)邏輯來產(chǎn)生頁面——我們可以簡單地輸出原先緩存地內(nèi)容。
  這種方法需要解決唯一地標識緩存文件的問題。如果一個站點是被一個顯示基于GET變量的中心腳本所控制,對每個PHP文件只有一個緩存不會有什么幫助。例如,如果index.php?page=about_us和用戶調(diào)用index.php?page=contact_us得到的顯示完全不同。
  問題是通過給每個頁面產(chǎn)生一個唯一的cache_id來解決的。為了做到這個目的,我們把事實上被請求的文件變成REQUEST_URI(基本上就是整個URL:index.php?foo=bar&bar=foo)。當然,這個轉(zhuǎn)換過程是受到CachedTemplate類控制的,但是要記住的重要的事情是你絕對要在創(chuàng)建CachedTemplate對象時傳遞一個唯一的cache_id。當然下面有例子來說明。
使用緩存包括以下步驟。

  1. include() 模板源文件
  2. 創(chuàng)建一個新的CachedTemplate對象(并且傳遞路徑,唯一的cache_id和緩存過期時間給模板)
  3. 測試內(nèi)容是否已經(jīng)被緩存了
  4. 如果還促拿了,顯示文件并且結(jié)束腳本
  5. 否則,進行所有的處理并且fetch()模板
  6. fetch_cache()的調(diào)用將自動產(chǎn)生一個新的緩存文件
  這個腳本假定你的緩存文件將放到./cache/中,因此你必須創(chuàng)建那個目錄并且改變它的目錄權(quán)限(chmod)使得Web服務(wù)器能夠?qū)懭胛募6疫要注意如果你在編寫腳本的過程中發(fā)現(xiàn)了錯誤,錯誤也會被緩存!因而在你開發(fā)的過程中禁用緩存是一個好主意。最好的辦法是給cache的生存周期傳遞0——這樣,緩存總是立即就失效了。
由于排版需要,請點擊以下地址查看全文:

出處:CSDN
責任編輯:cjj

◎進入論壇網(wǎng)絡(luò)編程版塊參加討論

相關(guān)文章 更多相關(guān)鏈接
ExpressionEngine模板設(shè)計大賽
PHP5 安裝方法
學(xué)習(xí)使用PHP數(shù)組
[php]一次編寫,隨處運行
PHP4之真OO
作者文章
[php]一次編寫,隨處運行
[PHP]超越模板引擎
關(guān)鍵字搜索 常規(guī)搜索 推薦文檔
熱門搜索:CSS Fireworks 設(shè)計比賽 網(wǎng)頁制作 web標準 用戶體驗 UE photoshop Dreamweaver Studio8 Flash 手繪 CG
站點最新 站點最新列表
周大!熬•自然”設(shè)計大賽開啟
國際體驗設(shè)計大會7月將在京舉行
中國國防科技信息中心標志征集
云計算如何讓安全問題可控
云計算是多數(shù)企業(yè)唯一擁抱互聯(lián)網(wǎng)的機會
阿里行云
云手機年終巨獻,送禮標配299起
阿里巴巴CTO王堅的"云和互聯(lián)網(wǎng)觀"
1499元買真八核 云OS雙蛋大促
首屆COCO桌面手機主題設(shè)計大賽
欄目最新 欄目最新列表
淺談JavaScript編程語言的編碼規(guī)范
如何在illustrator中繪制臺歷
Ps簡單繪制一個可愛的鉛筆圖標
數(shù)據(jù)同步算法研究
用ps作簡單的作品展示頁面
CSS定位機制之一:普通流
25個最佳最閃亮的Eclipse開發(fā)項目
Illustrator中制作針線縫制文字效果
Photoshop制作印刷凹凸字體
VS2010中創(chuàng)建自定義SQL Rule

藍色理想版權(quán)申明:除部分特別聲明不要轉(zhuǎn)載,或者授權(quán)我站獨家播發(fā)的文章外,大家可以自由轉(zhuǎn)載我站點的原創(chuàng)文章,但原作者和來自我站的鏈接必須保留(非我站原創(chuàng)的,按照原來自一節(jié),自行鏈接)。文章版權(quán)歸我站和作者共有。

轉(zhuǎn)載要求:轉(zhuǎn)載之圖片、文件,鏈接請不要盜鏈到本站,且不準打上各自站點的水印,亦不能抹去我站點水印。

特別注意:本站所提供的攝影照片,插畫,設(shè)計作品,如需使用,請與原作者聯(lián)系,版權(quán)歸原作者所有,文章若有侵犯作者版權(quán),請與我們聯(lián)系,我們將立即刪除修改。

您的評論
用戶名:  口令:
說明:輸入正確的用戶名和密碼才能參與評論。如果您不是本站會員,你可以注冊 為本站會員。
注意:文章中的鏈接、內(nèi)容等需要修改的錯誤,請用報告錯誤,以利文檔及時修改。
不評分 1 2 3 4 5
注意:請不要在評論中含與內(nèi)容無關(guān)的廣告鏈接,違者封ID
請您注意:
·不良評論請用報告管理員,以利管理員及時刪除。
·尊重網(wǎng)上道德,遵守中華人民共和國的各項有關(guān)法律法規(guī)
·承擔一切因您的行為而直接或間接導(dǎo)致的民事或刑事法律責任
·本站評論管理人員有權(quán)保留或刪除其管轄評論中的任意內(nèi)容
·您在本站發(fā)表的作品,本站有權(quán)在網(wǎng)站內(nèi)轉(zhuǎn)載或引用
·參與本評論即表明您已經(jīng)閱讀并接受上述條款
推薦文檔 | 打印文檔 | 評論文檔 | 報告錯誤  
專業(yè)書推薦 更多內(nèi)容
網(wǎng)站可用性測試及優(yōu)化指南
《寫給大家看的色彩書1》
《跟我去香港》
眾妙之門—網(wǎng)站UI 設(shè)計之道
《Flex 4.0 RIA開發(fā)寶典》
《贏在設(shè)計》
犀利開發(fā)—jQuery內(nèi)核詳解與實踐
作品集 更多內(nèi)容

雜⑦雜⑧ Gold NORMANA V2