當我第一次見到php模板的時候,簡直被迷上了。原來php世界里還有這么好的東西。我瘋狂地學習。
好在當時的php模板還不是很龐大,很快我了解了它的原理,并也能自己寫一些了。
后來,smarty橫空出世,更是擁有了許多為它著迷的fans.許多人開始寫模板引擎,將smarty或其他模板加以改造,使之符合自己的需要。
縱觀當今模板世界,php模板引擎主要分為兩種:
一種是替換特定字串型的。美工做出來的頁面,中間會嵌入一些什么{block.title}這樣的字符串,然后程序讀入這個模板文件,將中間的{block.title}的字樣替換成實際從數據庫中讀取的內容。
還有一種符雜一些,是一種編譯型的。以smarty為代表,模板文件中實際上包含了一些簡化的php代碼,比如有的寫的是<{=$site_name}>,<{if $counts>0 }>這樣的語句,實際是一種自行定義的語言格式。web開發久的人一眼能看出它們指的是什么。這一類往往會在第一次訪問時被預編譯,轉換成一個php文件何存起來。比如 <{=$site_name}>就變成了,<{if $count>0 }> 就變成了0) {?>。從第二次起,就直接包含已經編譯出來的php文件。當然,各種模板的處理的具體細節不一樣。
但是,我們為什么要用模板?
這個問題我也不能很好的回答。但是有很多人這么說:要讓美工和程序員的工作分開。要讓代碼層和表現層分開。
那么我們看這兩種方式實現了嗎?
讓您的美工人員打開一個smarty文件,讓他按他的思路去改一下視圖設計。他會告訴您,天哪,你怎么把我的設計變成這樣一幅樣子了?這些foreach,if都是什么意思?噢,天哪,我的表格怎么撐得這么大了?….
原來編譯型的模板技術讓美工更沒法子做美工了。
那么替換字符串型的呢?看起來是輕松多了。不過您可以測測您的程序速度,看看他是否已經慢了一倍以上。很容易,您用了太多的有preg_match,或是str_ireplace之類的語句來替換。程序重復一次又一次在您那幾萬個甚至更多字節的模板文件中查找某個字串,來替換內容。
不僅如此,你還發現您哪天想在視層面插一點東西時,處處受制于模板。您肯定很想直接在模板中寫一段之類的語句,但是,很抱歉,您不能這么寫。如果只是想echo 一個什么東西,您可以在模板中加一個{{var}}的串,然后在php程序中寫
$var=”這一個串”;
$template->assign(”var”,$var);
但是如果您不是想輸出呢,想做其他操作?抱歉,您還是得改php代碼。這些模板都支持規矩矩的表格狀的輸出,但是,如果我想輸出20條記錄,我要弄一個第一行2列記錄的,第二行3列的,第三行又是2行的之類的,或者是其他類似找碼,您打算怎么辦?
難道再讓您的模板引擎也升級成為編譯性的,好讓您往您的模板中加入php語句?
您錯了。其實,我們看一看,我們的模板引擎充當了什么樣的角色呢?我們把一段特定的按一定規則編寫的html代碼進行一定的數據處理后輸出成了另外一段,輸出過程中某些字符發生了改變。那我們的偉大的php干了什么呢?它幫我們把我們按規則寫好的php代碼也按一定規則輸出成了一段html。兩者本質是一樣的。只是,php本身比我們那些蹩腳的模板引擎更快,更漂亮。
再說細一點,現在用的最多的Smarty.看一看它的結構:
<{if $article.rates}>
<span class="title"><{php}>echo art_constant("MD_RATE");<{/php}>:</span>
<span class="item"><{$article.rating}>/<{$article.rates}></span>
<{/if}>
你覺得它是一個美工能看清的html文件么?
看看編譯后的結果,它看起來應該是這樣的:
<?php
if($articles.rates){
?>
<span class="title"><?php echo art_constant("MD_RATE");?>:</span>
<span class="item"><?php echo $article.rating;?>/<?php echo article.rates;?></span>
<?php
}?>
哈。我們偉大的smarty把這html也變成了php了。然后在以后的工作中,這些php代碼會直接被運行。
有必要嗎?本來是apache承載php,php直接編譯php 源代碼,現在變成了apache承載php,php編譯smarty引擎,smarty引擎又去編譯html文件。反而多了一層,smarty自個兒把本來php要做的工作拿了做了。
而且糟糕的是,smarty的模板打開來以后,比php文件更讓人難以看清。
所以我說,放棄您的模板系統吧。但記住我們開發模板系統的初衷。
您會說:那要是放棄模板系統了,我怎么分開程序邏輯和視圖層面?
這個也太好辦了。您可以這樣寫:
第一個文件這樣寫:
<?php
/**
file :logic.php
@author renlu xu<helloasp@hotmail.com>
@link http://www.162cm.com
*/
$rs=mysql_query("select id,title,body from articles order by id desc limit 30");
while($row=$mysql_fetch_assoc($rs))
{
$rows[]=$row;
}
?>
第二個文件作為您的視層面的文件。您可以讓您的平面設計師在mac上設計漂亮絕頂的圖片,然后切成html文件,交給您的頁面整合工程師。這個工程不需要懂太多php,他基本上只需要會用print就行了。他把這個html文件改名為view.php,然后在里面加上相應代碼:
<?php
/**
file:view.php
@author renlu xu<helloasp@hotmail.com>
@link http://www.162cm.com
*/
foreach($rows as $row)
{
echo "<tr>";
echo "<td>";
echo $row["id"];
echo "</td>";
echo "<td>";
echo $row["title"];
echo "</td>";
echo "</tr>";
}
?>
ok.這就視層面文件。這個文件用織夢者(dreamweaver)打開后,應該跟美工做出來的圖是一樣的,就僅僅多了用那個黃色的問號代表的php代碼。寫得好時,dreamweaver還能列出您的php代碼中輸出了什么內容,效果更佳。
這兩個文件,就是一個是邏輯層,一個是視層面。
然后用index.php將他們包含起來。
<?php
/**
file:index.php
@author renlu xu<helloasp@hotmail.com>
@link http://www.162cm.com
*/
include "databaseConnect.php";//連接數據庫的代碼,我就不寫了
include "logic.php";
include "view.php";
include "cache.php";
?>
這樣邏輯和視,就分開了。那有人會說,如果我用模板,可以將要輸出的內容寫入到靜態文件中,現在沒了模板我該怎么辦?
這個不是問題。我們用的是php,超酷的php.
看看,我們加了cache.php.這就是用來實現您說的緩存效果的。
我們的cache文件:
<?php
/**
file:cache.php
@author renlu xu<helloasp@hotmail.com>
@link http://www.162cm.com
*/
$content=ob_get_content();
$fp=fopen("index.html","w");
fwrite($fp,$content);
fclose($fp);
?>
當然,index.php也改成:
<?php
/**
file:index.php
@author renlu xu<helloasp@hotmail.com>
@link http://www.162cm.com
*/
if(file_exists("index.html"))
{
include "index.html";
exit();
}
include "databaseConnect.php";//連接數據庫的代碼,我就不寫了
include "logic.php";
include "view.php";
incldue "cache.php";
?>
這樣您看這緩存效果是不是就出來了?
有人說:我用模板還有一個好處啊,就是模板寫錯了還不會影響到程序的運行。是的。咳,怎么說呢?您在模板中將<{=$site_name}>寫成了<{=$sie_name}>是沒啥,您的php程序還是很”健壯”地運行著。不過您沒覺得,當您期望的那一個將由<{=$site_name}>來打出來的網站名稱沒有出現的時候,您排起錯來會很難找嗎?對于一個程序師來說,您不覺得,光只視層面的那些echo語句,只應該是您工作中極微不足道的一部分嗎?在這個主要是echo語句構成的視層面文件view.php,您還出現編譯期錯誤,是不是該拉出去打屁屁?
另外,在php程序正式上線運行時,您也可以將它的報錯功能關閉啊。