| 每個進行過較大型的PHP-Web應用程式設計的開發人員大概都有如下的經曆:花大量的時間寫超文本語句,為頁面排版,兼作美工等;或在整合的程式碼在和HTML靜態頁面時花費大量的時間。的確,用指令碼語言開發Web應用不容易將資料的處理和資料的顯示分開,但在多人合作的情況下,如果無法將資料和顯示分開,將大大影響開發的效率,專業分工的發揮。為瞭解決這個問題,PHP也提供了自己的解決方案,有多種,本文主要介紹PHPLIB中的Template類。 1 模板處理類的設計 模板處理類主要需完成以下的任務: ·從模板檔案中讀取顯示用的HTML代碼。 ·將模板檔案和實際產生的資料結合,產生輸出的結果。 ·允許同時處理多個模板。 ·允許模板的嵌套。 ·允許對模板中的某個單獨的部分進行處理。 歸納上述任務,模板類的設計目標為:從多個模板檔案中讀入顯示的HTML代碼,將這些顯示代碼中需要動態資料的地方替換為PHP程式運算所得出的資料,然後按照一定的順序輸出。其中,替換的部分可以自由的設定。 讀取顯示用的HTML代碼採用讀檔案的方式 模板檔案和資料的結合採用正則替換 處理多個模板用數組儲存來實現。 模板的嵌套的實現主要的想法是:將模板和輸出(任何中間的分析結果)一視同仁,都可拿來做替換,即可實現。 單獨部分的處理的通過在模板檔案中設定標註,然後在正則替換中結合標註來控制,實現部分替換。 2 模板處理類的實現 請參看PHPLib中的Template.inc,總共345行代碼,有詳細的注釋。以下列舉一些主要的函數,供研讀參考: 1) function set_file($handle,$filename=” ”) line 77, 讀取檔案 2) function set_var($varname, $value = "") line 119, 設定映射資料-替換變數 3) function set_block($parent, $handle, $name = "") line 96, 設定標註 4) function subst($handle) line 136, 執行資料替換 5) function parse($target, $handle, $append = false) line 165, 執行模板檔案與資料的結合 6) function p($varname) line 268, 輸出處理結果 註:本人下載的php-lib7.2c的Template.inc檔案中的第95行少了個“/”,加上後使用正常。 3 模板處理類的使用 3.1 最基本的例子 為了簡單起見,這裡假設模板檔案、使用模板的PHP檔案和模板處理類的檔案都放在同一個目錄下。PHPLIB中的習慣是使用ihtml尾碼為模板檔案的尾碼。 下面是要使用的模板檔案: <html> <head> <title>使用模板的測試</title> </head> <body> <h2>這是一個使用模板的測試檔案!</h2> 當前的時間是{currenttime}! </body> </html> 註:模板檔案和通常的HTML檔案差不多,唯一不同的是使用“{}”括起來的是可以被模板處理類替換的動態內容的變數。 接下來使用模板處理類來處理上面的模板: <? //引入Template類 include("template.inc"); //得到需要替換的資料 $timeNow=date("Y-m-d H:i:s",time()); //執行個體化一個Template類 $template= new Template(); //載入test.ihtml模板 $template->set_file("handle1","test.ihtml"); //使用$timeNow的值替換模板中的currenttime $template->set_var("currenttime",$timeNow); //進行實際的模板操作 $template->parse("output","handle1"); //輸出最後結果 $template->p("output"); ?> 註:如果只想用PHPLIB中的模板類,只需在檔案頭包含Template.inc類即可。 建立Template對象時,可以指定模板檔案路徑,如:new Template(“/htdocs/apps/templates/”),預設為當前路徑。 3.2 模板嵌套與塊設定 下面這個例子來自與PHPLIB的參考手冊,綜合性較強,這裡需說明的一點是設定塊的目的與嵌套無關,但這個範例包含了兩者。請仔細閱讀,塊設定是為了避免這種情況:原本可在一個模板檔案(靜態頁面)裡完成的內容,因需要部分迴圈,而將部分迴圈內容提取單獨做成模板檔案。請思考,如果不用塊設定,這個例子是不是需要3個模板檔案呢? 模板檔案1,page.ihtml <html> <head><title>{PAGETITLE}</title></head> <body bgcolor="#ffffff"> <table border=1 cellpadding=4 cellspacing=0 bgcolor="#eeeeee"> <tr> <td colspan=2><h1>{PAGETITLE}</h1></td> </tr> <tr> <td>{OUT}</td> <td>Content</td> </tr> </table> </body> </html> 模板檔案2,box.ihtml <!-- start box.ihtml --> <table border=1 bgcolor="#cccccc" cellpadding=4 cellspacing=0> <tr> <td colspan=2><b>{TITLE}</b></td> </tr> <!-- BEGIN row --> <tr> <td>{NUM}</td> <td>{BIGNUM} </tr> <!-- END row --> </table> <!-- end box.ihtml --> 模板處理檔案,test.php <?php //引入Template類 include("template.inc"); #執行個體化一個Template類,名字叫$t $t = new Template(); # 建立包含模板檔案的數組 $t->set_file(array( "page" => "page.ihtml", "box" => "box.ihtml")); # 載入模板檔案box中的一個塊row,引用名稱為rows $t->set_block("box", "row", "rows"); # 設定替換 $t->set_var(array("TITLE" => "Testpage", "PAGETITLE" => "hugo")); # 產生資料NUM,BIGNUM for ($i=1; $i<=3; $i++) { $n = $i; $nn = $i*10; #設定替換 $t->set_var(array("NUM" => $n, "BIGNUM" => $nn)); #進行分析,分析的結果添加到rows的後面 $t->parse("rows", "row", true); } # 產生box,再產生page $t->parse("OUT", array("box", "page")); # 輸出最後結果 $t->p("OUT"); ?> 註:這裡page.ihtml模板檔案中變數的命名與最後的輸出控制代碼都用了“OUT”。 迴圈取值部分採用資料庫類,即可將資料的產生與資料庫應用結合起來。 執行結果如: 模板嵌套與塊設定執行結果圖 4 小結 本文主要簡要介紹了PHPLIB中Template類的設計、實現及使用方法。當然,還有許多其他的PHP模板方案,如由Perl中演化而來的FastTemplates。目前Internet小組採用的是另一種方案,主要的實現方式是模板檔案入庫,採用eval來實現資料與模板檔案的結合等,相對來說模板檔案的管理與模板處理的使用比較簡潔,但缺少檔案存放的模式。本人目前在做的一些嘗試是將兩者結合起來,並想在PHPLIB的Template類的基礎上進行改進。初步的目標任務有兩個:1、在讀模數板檔案時擴充其對資料庫的支援,這樣可以在必要時增強靈活性與使用資料庫管理工具 2、化簡模板檔案與資料的結合,因為在實際使用中大多數情況下無需將模板檔案中的變數在處理常式中再設定(資料變數映射)一遍。 在此也希望讀者、PHP程式愛好者一起參與進來,多提寶貴意見,祝好運! |