最近更新: 2007-01-29

PHP 不需要另一個樣版引擎 (Smarty, PHPLib, etc)

前幾天我看到 phpPatterns 的《PHP and Templates》,作者舉了很多例子說明 PHP 不需要使用樣版引擎。我個人的經驗與該作者一樣, PHP 確實不需要使用樣版引擎。因為 PHP 本身就是一種樣版引擎,在樣版引擎上再加一個樣版引擎是多此一舉。

先看看 XML 和 XSLT 的例子。對 XML 而言, XSLT 就是它的樣版引擎, XSLT 以樣式規則 ( pattern) 決定一份 XML 文件的呈現時的內容。在某方面而言, XSLT 其實比較像是一個程式語言。然而,沒有人會說我們需要為 XSLT 設計一套樣版引擎。再看看 PHP 設計時的基本用途。 PHP 從一開始就將其定位為 SGML, XML, HTML 等標籤語言 (markup language) 中的指令解析器。因此它按照 SGML 規範的表示法使用 <? / ?> 標示其存在,而不是 ASP, JSP 所用的 <% / %> (這是什麼玩意?) 一如我們用 <?xml ?> 表示標籤中的指令交由 XML 解析器處理,因此用 <?php ?> 便表示此標籤中的指令交由 PHP 解析器處理。而 PHP 解析器在 SGML 中的作用,便是以程式邏輯指令決定文件呈現時的內容。毫無疑問, PHP 就是標籤語言文件的樣版引擎。

實務上,使用一套樣版引擎便需要學會一套樣版描述語法。然而和 PHP 語法相比,那些樣版語法未必容易理解。看看下面的例子,我用 Smarty 和 PHP 語法並列。有什麼理由說樣版語法比 PHP 語法容易理解與使用呢?使用 PHP 語法就是比樣版語法直接了當。

<title><?php echo $title?></title>
<title>{$title}</title>
<table>
<?php foreach ($rows as $row): ?>
    <tr>
        <td><?php echo $row['poster']?></td>
        <td><?php echo $row['comment']?></td>
        <td><?php echo date('Y-m-d', $row['timestamp'])?></td>
    </tr>
<?php endforeach; ?>
<tr
</table>
<table>
{foreach from=$rows item=row}
    <tr>
        <td>{$row.poster}</td>
        <td>{$row.comment}</td>
        <td>{$row.timestamp|date_format:"%Y-%m-%d"}</td>
    </tr>
{/foreach}
<tr
</table>

還有一點,對大多數網頁編輯環境而言,如 DreamWeaver , PHP 標籤是可以理解的,而 {/} 標籤沒有意義。 PHP 標籤是一個合於格式的一般標籤,在網頁編輯環境中,如果可以處理就會解析,反之則僅顯示而不處理。如 DreamWeaver 便會將 PHP 標籤的內容顯示為一個 <php> 的圖案。

或許還有人會舉出一個理由,說 Smarty, PHPLib 可以快取已經解析過的內容,減少資料重覆讀取與解析的動作,提昇系統效能。但是,那是快取功能而不是樣版功能。透過單純的 Cache library 就可以做到,不需要弄來一套樣版引擎卻只用它的快取功能。

還有一個趨勢可以看出有愈來愈多人認為 PHP 不需要樣版引擎。那就是最近出現的 framework 皆只提供快取功能而不再使用任何樣版引擎。像 CakePHP, Code Igniter 等,它們的設計者都不認為 PHP 需要樣版引擎,在 View 的設計工作中皆直接使用 PHP 語法。現在有愈來愈多 PHP 程序員開始使用 CakePHP 這些 framework 。由於這些 framework 並不使用樣版引擎,因此 PHP 程序員將有更多機會體會到直接使用 PHP 語法會比套用 Smarty, PHPLib 那些樣版引擎更簡單。

樂多舊網址: http://blog.roodo.com/rocksaying/archives/2680742.html

樂多舊回應
HACGIS@gmail.com(tokimeki) (#comment-3896538)
Tue, 30 Jan 2007 05:28:40 +0800
我個人對這種說法持保留意見。
我認為樣板系統對於如何構成畫面提供了一個一致性的流程與結構,透過學習並使用樣板系統,可以讓程式設計師的工作輕鬆不少,也保證了一定程度的程式品質。
未留名 (#comment-3896961)
Tue, 30 Jan 2007 10:14:52 +0800
tokimeki 說得很對。

工程師有一個非常大的缺點,就是喜歡把自己覺得可行的東西硬套到其他成員身上。而我也是其中一個,只不過我學到了很多教訓。

當初會想要學習 Smarty ,其實就是因為身邊的伙伴完全不懂 PHP 。對他們來說,能夠簡單快速是最好的;所以不僅是 PHP 而已,就連 HTML 和 CSS 他們都非常依賴工具。

當然目前多數視覺開發工具對 PHP 語法的支援度不是那麼良好,就算是 Dreamweaver 也不是那麼完美。我的經驗裡,讓他們使用能支援 Smarty 語法的編輯器,對我們在溝通上來說會比完全沒辦法看到程式來得好些。

除此之外,像 Smarty 這樣的樣版引擎還有一個好處,那就是 plugins 的 reuse 。當然 PHP 本身的語法也能辦到,不過比起一個簡單的 Smarty 語法,你在原生的 PHP 語法裡必須重複寫上好幾行程式才能做到。我不反對拿 PHP 的語法直接當做樣版引擎語法,但是無論如何都要保持簡單與易懂。

我常抱持著一個觀念:那就是國外的趨勢不能拿來台灣硬套,要套也要稍作修整。我敢說,要在台灣能夠接案開發 (當然玩票或研究性質不算) ,除非是「一人團隊」或是超級高手所組成的公司,否則就目前現有的框架是沒有辦法能夠在台灣提供生存機會的。

如果能夠跟身邊的伙伴有良好溝通的話,我想有沒有樣版引擎其實都無所謂, Team Work 才是真正的重點。

抱歉在你的 Blog 造次,我只是想提出我的經驗供你參考。
未留名 (#comment-3897005)
Tue, 30 Jan 2007 10:30:04 +0800
唉,先改一下標題好了。從「PHP 不需要樣版引擎」改成「PHP 不需要另一個樣版引擎」。

PHP 本身就是一個 SGML,XML,HTML 等 markup language document 用的解析器 (parser) ,所以就像一份 XML 文件必須標示 一樣, PHP 要求自己包含在 標籤中。上文說了,這是 SGML 規範內容。儘管我們可以把 PHP 當一個純粹的程式語言,但還是要把 code 放在標籤中。這個怪僻在 Perl, Python, Ruby 中可看不到。

繼續觀看其他回應 part 2 - 補充與回應
未留名 (#comment-3897023)
Tue, 30 Jan 2007 10:37:10 +0800
jaceju said: 像 Smarty 這樣的樣版引擎還有一個好處,那就是 plugins 的 reuse

這點也不成立。我會把重複可再用的語法,寫在另一個 php 中,讓 View 掛入。你可以看看 CakePHP, Code Igniter 的做法。它們的 Help 就是你說的 plugins 。它們通常在 Controler 中載入 Help (plugins) ,在 View 裡面調用。只要你願意,你也可以在 View 中載入 Help ,除了語法差異,跟 Smarty 沒兩樣。
未留名 (#comment-3897214)
Tue, 30 Jan 2007 11:43:50 +0800
嗯,我想...這點還是個人的經驗問題,我個人是有自己一套 語法 reuse 上的觀點,我也不認為你能全盤接受;因為我們開發的環境或許不能類比,因為我接觸過的 PHP 案子不多,所以我想我的經驗還是不足以供你參考。

還是老話一句:想想你身邊的伙伴,他們能接受什麼就是什麼,我們認為對的想法,不一定能套用到他們身上。

以上是個人拙見。
未留名 (#comment-3897311)
Tue, 30 Jan 2007 12:24:26 +0800
我沒提到的個人經驗是,我曾經想讓網頁設計師用 Smarty 。是我忍住我的不便,想讓身邊的伙伴輕鬆一點。然而結果被打回票。

Smarty 沒有程式設計師所設想的有用,「反正都是程式設計師搞出來的怪玩意,只有你們看得懂。」我上次工作的那家軟體公司的網頁設計師如此說。
whsinyee@hotmail.com(Mark) (#comment-3897517)
Tue, 30 Jan 2007 13:45:48 +0800
其實我滿贊同的。

尤其是當我現在維護的 LifeType 整個是由 Smarty 組成的時候,你就知道用 Smarty 時的噁心。

其實並非 PHP 使用樣版引擎不好,而是使用樣版引擎到底對目前的工作有沒有加速,效能有沒有提升。

PHP 最大的問題就是『髒』。所有程式、頁面設計全部集中在一起。樣版引擎的出現,只是讓 PHP 的程式設計師開始想想該怎麼寫一些乾淨的程式。

可是使用 Smarty/PHPLib 後所造成的程式 Overloading,又讓大家回頭過來思考,是不是畫蛇添足了。因為 PHP 本身就是 Template Engine,幹麻要在 Template Engine 上又加上一個 Template Engine....

所以就像石頭說的 CakePHP, Symfony 都用 PHP 的 tag 來做樣版引擎,而不再另外發明。但是那跟原來『髒』的寫法差在哪裡?

差在現在寫程式更有規矩了!因為目的放再把邏輯與樣本分開,而不再用什麼 tag。所以即使用 PHP 本身當作樣版引擎,PHP 程式也不再髒了。

所以 PHP 需不需要另一個樣版引擎?看各人喜好吧!只是功能越強大的樣版引擎如 Smarty,越需要強大 CPU、強大的 I/O 功能,強大的 Opcode Cache。否則當程式越大,跑得越慢。 :(

就這樣的觀點看來,我越來越喜歡歡用 PHP 本身來當作樣版引擎,而不另外發明。

BTW, 如果有一天 PHP 的 JAVA/NET Compiler 都成熟了,那麼用 Smarty/PHPLib 來當作樣版引擎時,對效能可能就不會有那麼大的影響了。另一個作法,是把 Smarty 寫成 Native PHP Extension。

Mark
未留名 (#comment-3897737)
Tue, 30 Jan 2007 15:18:04 +0800
既然提到 LifeType ,我也說說 Xoops 吧。

我上次在專案中使用 Smarty ,是在 Xoops 下開發新的模組。最初也是計劃依著 Xoops 架構用 Smarty 的樣版設計頁面。但就像我前面說的一樣,網頁設計師拒絕我的「好意」。所以前台頁面照他們的老方法,先設計好再丟給程式設計師嵌 tag 。

前台不用了,還有後台的頁面。我就用 Smarty 去設計,寫著寫著就漸漸不耐煩了... 或者,像 Mark 說的,噁了。專案還沒進行到一半,就把 Smarty 的樣版語法清掉了,直接用 PHP 語法。只用 Smarty 的 cache 功能。

Smarty/PHPlib 對純粹的 PHP 程序員來說,有「強迫」他們養成將頁面和業務邏輯分離的作用。然而我寫 C/C++ 時就養成了 MVC 架構的習慣,這習慣也帶到 PHP 中,是以我並不需要 Smarty/PHPLib 「輔助」我分離兩者。而且 CakePHP 那些 framework 的架構也同樣有助於 PHP 程序員養成頁面與業務邏輯分離的習慣。

我想 Smarty/PHPlib 或許已經完成其階段性任務了。
未留名 (#comment-10822641)
Thu, 07 Jun 2007 11:13:10 +0800
不好意思,我實在很懷疑版主究竟有沒有用過smarty??

我不否認,在用smarty架構網站的過程,確實辛苦,但是這是先苦後甜

除非確定這個站100年之內不改版,否則一但需要版面大翻修的時候

你就會慶幸,當初有使用smarty了

就我現在公司所維護的網站,沒有用smarty,php和html全部混在一起

要改版面那才叫痛苦,因為原始程式不是我寫的。

當然如果當初有用SMARTY,叫美工直接去改smarty的佈景檔,不見得可行

所以我還是叫美工設計好後,我再自己去套版面。那這樣有沒有用smarty有什麼不一樣?

當然不一樣,比不用smarty的情況好套太多了

php本身就是樣板引擎?? 好~那請問php要如何做到smarty那樣,把php和html分的乾乾淨淨??

MVC?? 那不算!! 基本上用MVC的只有寫的人很爽,以後維護的人就要倒大霉,程式被拆得到處都是

檔案呼叫來呼叫去,去研究還不如重寫


「像 CakePHP, Code Igniter 等,它們的設計者都不認為 PHP 需要樣版引擎,

因此 PHP 程序員將有更多機會體會到直接使用 PHP 語法會比套用 Smarty, PHPLib 那些樣版引擎更簡單。」

會這樣講代表他們根本不知道SMARTY的真義。我也覺得,直接用PHP語法結合HTML,好簡單,好快,一目了然

相信大家都同意。但是一開始爽的結果,以後要修改版面就知道痛苦了


如果不會覺得痛苦的,那一定是他的網站規模很小,PHP程式不多,那當然不需要SMARTY也無所謂
未留名 (#comment-10832043)
Fri, 08 Jun 2007 00:40:03 +0800
Smarty 難道就不是一種邏輯性語法嗎?在 HTML 裡面混雜一堆 Smarty 語法就算是分得乾淨喔?你找個網頁設計師問問看吧。

唉。前面那麼多人討論的內容都白說的了。
lman@brain-c.com(梁楓) (#comment-11122757)
Wed, 04 Jul 2007 00:54:18 +0800
嗯,我個人常做的事是...

在程式碼最後,把HTML 另外用 Include 進來...
然後 PHP CODE 是我平常在做的
美工就變HTML

當初用Smarty是為了我debug方便
(當可以看到一整個頁面產生了那些變數及變數的內容,那有多爽啊)

不過,隨著我改用Zend Studio後,這個功能就變的不是那麼必要了...

可惜,PDO好像不能把我要的SQL語法送出來做debug,我只好繼續用adodb
未留名 (#comment-11131309)
Wed, 04 Jul 2007 16:42:06 +0800
嗯,你是指 PDOStatement 不能讓你看到實際送出的 SQL 查詢敘述嗎? 用 PDOStatement 時,應該沒有這方面的需求吧?不過我自己都不用 PDOStatement ,好像不適合說這話。

我現在仍然習慣自己丟字串,還自己弄 prepare 功能,如 To Prepare SQL Statements
sjhuang.tw@gmail.com(Jason) (#comment-14903641)
Fri, 02 Nov 2007 13:54:29 +0800
我贊同版主所說的,
自己用 smarty 也覺得很麻煩,
現在都是要設計直接設計一些網頁的樣板給我(就是一般網路上看到的那些)
他只要提供 html jpg css
然後我把php產生的內容資料貼進去,
這樣可以很快的產生客戶要的東西。
小改版的話,
只要客戶改掉 css 和 jpg 就可以,
大改版的話,
我又有錢賺了!
未留名 (#comment-16857929)
Mon, 14 Jul 2008 18:34:32 +0800
版主,拜讀您的文章後,也很贊同您所說如果程式設計師寫程式時依據MVC架構,就不需要用 Smarty 將 presentation layer 和 business logic layer 分開。

我現在正準備開發一個新的網站,framework 打算用 CakePHP,但暫時對 caching 還沒有頭緒。您之前提及
「專案還沒進行到一半,就把 Smarty 的樣版語法清掉了,直接用 PHP 語法。只用 Smarty 的 cache 功能。」。

請問用 Smarty 的 cache 功能是一個逼不得已的方法,還是有可取之處呢?

我的要求是不同版面都會有不同 cache 的有效時間,在同一個頁面不同版塊cache 的有效時間也不同,還有分頁的 cache 。 這些要求似乎 Smarty 都能一一處理,還是有更好的方法呢? 因為我較擔心 Smarty 要同時用accelerator才會有較好的 preformance。

請賜教,謝謝。
tw.alan@gmail.com(wcchi) (#comment-17097691)
Tue, 19 Aug 2008 14:54:24 +0800
見仁見智!

如果版面設計跟程式是兩個人做的,那smarty倒真的幫上大忙。

做版面的完全不懂程式,那光靠MVC 是沒辦法好好分工吧。
未留名 (#comment-17286697)
Thu, 28 Aug 2008 01:59:26 +0800
樓上的似乎還是沒抓到這篇文章的重點...
iamadog@gmail.com(iamadog) (#comment-18170365)
Wed, 17 Dec 2008 07:16:35 +0800
聽你在亂講...
CakePHP 裡面的 VIEW 就是一種樣版系統阿
不然你把 VIEW 系統拿掉試試看阿
abbychau@gmail.com(abbychau) (#comment-19652115)
Mon, 10 Aug 2009 02:53:04 +0800
我是支持這篇文章的觀點的
我在各個template engine 中爭扎了不少時間,
發覺php 自己不是一直也是奉行MVC 嗎? 只是語法和原來的一模一樣罷了...說到這個地步, 希望大家明白, 寫template 的時候不要如axis 所說的php 和html 混到亂七八糟

- 我一直認為比好看多了, 也更像在寫模版(好了, 我不再說這種膚淺的事)

- 和template engine 的寫法一樣, 重覆的分一分模組
- functional的在上面寫好, 不要帶到template
- 如果有些方法或者重覆的處理會出現的話, 寫一個公共的library...放在上面

做得好的話, 會比用template 更易讀
因為在

{foreach from=$rows item=row}

這種地方, {foreach from=$rows item=row}本身對於xhtml 來說就是不會語法的
未留名 (#comment-19944117)
Wed, 14 Oct 2009 15:20:39 +0800
我是支持石頭這一方
Smarty 我覺得語法都套在HTML 一點都不乾淨...
而且還要學習Smarty到現在還看不太懂...
我看到Smarty真的會吐寫...一下找模板~~一下找程式碼~~找來找去...
未留名 (#comment-21668587)
Thu, 17 Mar 2011 12:44:03 +0800
剛接觸PHP,使用Codelgniter的framework。從:

http://dyna.hcc.edu.tw/php5/advance/courses/class2_2.htm

中對Smarty 樣版的介紹中,的確有種其實PHP不需要另一個樣版引擎的感覺。
未留名 (#comment-21835379)
Wed, 29 Jun 2011 11:02:53 +0800
ㄜ...看起來就像公司員工相處問題..

美工人員不看原始碼...直接把Smaty前台的部分,又丟回給工程師自己改...

所以工程師每拿一次版面,就要自己再改一次~
未留名 (#comment-22139743)
Wed, 23 Nov 2011 12:46:22 +0800
RE 版主:
Smarty 難道就不是一種邏輯性語法嗎?在 HTML 裡面混雜一堆 Smarty 語法就算是分得乾淨喔?你找個網頁設計師問問看吧。


這句話我深感認同,使用了PHP撰寫數年程式,從未使用樣版,逐步的把自己code從髒語法,弄到自行規範的乾淨語法,連不懂程式的人都可以簡單的include就取用,後來學習了下smarty(主要是想瞭解catch部份),發現smarty在使"語法乾淨"這部份,對"我個人而言"顯得畫蛇添足,綁手綁腳,對於前端設計師而言,是種痛苦,得多學一樣東西,而catch部份其實也是有缺點的,當網頁資料上萬頁時,這部份會拖垮OS的loading,此部份已由許多大型論壇得證,是以..現階段我個人的情況是
1.我不使用額外framework (除 jQUERY / Mootools / Prootype這類)增加團隊及網管(機器)困擾
2.我的伙伴不需看懂程式,開好版面即可將程式在極短時間內完成佈局
3.機器用很低的loading就可以支撐,替公司省下不必要開銷
皆大歡喜就好
zivhsiao@gmail.com(Patrick) (#comment-22270947)
Tue, 10 Jan 2012 11:20:05 +0800
其實如果玩過MVC架構,對於Smarty應該不至於會有很大的排斥
簡單的說Smarty有點像一些Framework裡面的View部分
雖然將程式碼轉換成為Smarty tag的表現方式會覺得要學習一樣東西
不過我個人與美工的合作經驗,php code與smarty tags,美工比較能夠接受smarty tags

就算不小心將smarty tags清除掉,對我來說也能很快恢復回去
在很多時候,Smarty的確有不少的幫助

MVC其實造就了架構分離的模式,習慣就會慢慢的轉移將資料、邏輯、前端畫面分離

不論那一種方法,是否使用Smarty,其實需要的是將資料端、程式模組化處理好
不論是否使用Smarty或MVC,其實都會比較容易維護
t8965513@hotmail.com(Don) (#comment-22322676)
Wed, 22 Feb 2012 01:34:23 +0800
其實我是覺得使用Smarty是為了區分後端程式與前端頁面
以一個簡單的例子來說
A是程式
B是設計
在傳統的模式下,寫出來的程式是HTML+PHP的語法
如果沒有改版需求,這一切看起來就是美好的
但若需要改版的時候,問題就浮現了
B開始改版,A就措咧蛋,因為不知道B會不會動到程式的部分
改壞了A也只能認了

如果使用Smarty的話,B想怎麼改就怎麼改~壞了也不會影響到程式的邏輯
另一方面是兩者可以分工同時進行
對B來說Smarty的語法只要學變數的套用跟迴圈
比起PHP語法來說輕鬆很多
未留名 (#comment-22322870)
Wed, 22 Feb 2012 10:25:07 +0800
Don, 請仔細看完正文與後述回應。

你說的事「區分後端程式與前端頁面」其實是 PHP 的設計初衷,是PHP原來就要做的事。

我是從 PHP 2.0/3.0 時代就在用的老玩家,那時候的 PHP 就是作為前端頁面的樣版引擎,去搭配後端程式在用(那時是用C或Perl寫CGI的時代)。

再者,Smarty的語法不見得比PHP語法容易理解。至少以我只會用八、九種程式語言的水準來看,Smarty的語法實在難記。
tkdmaf@gmail.com(SAM) (#comment-22336382)
Sun, 04 Mar 2012 11:30:38 +0800
基本上我應該已經是一個codeigniter的重度玩家了。
2010年的8月,我參考了codeigniter的原始code有設計出一個非掛於framework的樣板引擎。
so?
因為我那個樣板引擎的內容本身就是讓view本體直接吃php的原生code。
不需要去做任何的轉換。
我認為如果要把樣板的內容先取出再切割或是另外寫他的解析模式是挺耗消資源和時間的。
雖然我當時從ci抽取出那個方法重寫一個class的目的也只是為了讓一些使用者能夠從他去理解ci的用法。
總之。我贊同石頭大的說法,php並不需要另一個樣板引擎來製造所謂的麻煩。
至於說MVC架樣或說php和html或是說程式碼和顯示的分家。
我不認為是以「view」本身有沒有php code這件事來看。
我認為是以view本是是否還在做流程處理以及資料處理這二件事來看。
如果你到了view階段都還在處理流程和資料。
那就是所謂的「混寫」,也就是一般php書籍的教學方法。
但如果view中只包含為了「輸出」所必須下的像是foreach或是重覆迴圈的for或是必要的判斷式if。
這種情形不能算是混寫。
雖然我也必須明白指出你在做這些事時要用以下做法:
基於某個原則上的錯誤:
<?php foreach($query->result() as $row){?>
<?php echo $row->name?>

<?php }?>
基於某個原則上的正確:
<?php foreach($query->result() as $row):?>
<?php echo $row->name?>

<?php endforeach?>
我個人習慣的用法(因為我會開啟CODEIGNITER的SHOWTAG功能,事實上我的伺服器也是會讓他支援)
<?php foreach($query->result() as $row):?>
<?=$row->name?>

<?php endforeach?>

不過在講這些樣板引擎的狀況下,要說好不好維護的同時我認為有沒有使用正確的整合開發環境比較重要。
如使用標準具備基礎語法除錯的整合開發環境或是有支援php語法的情形下。
我不認為維護這些code會有什麼難度。

當然青菜蘿蔔各有所好,石頭大在此也是講述他對樣板引擎的看法。
有人認同,有人反對。
最主要是不管你認同還是反對,你有接受「改變」的覺悟嗎?
無法適應任何可能的變動性,就很難生存的下去。
這是事實。
=======================
上面寫的CODE被吃了(當成tag被刪?)。我應該要預覽才對。
這一篇修正,石頭大可以的話幫我刪了上一篇。