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