PHP開發必備 一步步學PHP模版引擎Dwoo
PHP目前是使用最廣泛的腳本解析動態語言之一。在PHP的開發當中,開發者都很關心的一個問題是,如何最大程度地將頁面和商業邏輯分離。而目前的很多PHP的開發框架,在這方面都有很好的解決方案,比如Zend,Agavi,CakePHP和CodeIgniter。然而,假如你的項目不是太大而沒使用這些框架時,則可以選用一些開源的PHP模版引擎來實現頁面和邏輯的分離,目前比較著名的有Smarty。本文將介紹另一款新興的PHP模版引擎Dwoo,它同樣有很多優點,值得讀者去學習。
一、安裝Dwoo
首先到Dwoo的官方網站下載(http://www.dwoo.org)最新的版本1.1.7。在下載后,解壓dwoo,將解壓目錄命名為dwoo,當然,你也可以用pear的安裝方法安裝,方法為:
pear channel-discover pearhub.org
pear install pearhub/Dwoo
二、Dwoo模版簡介
在Dwoo中,跟象Smarty等模版引擎差不多的是,它允許用戶用普通的HTML編輯工具編輯表現層的頁面,然后在需要產生動態內容的地方用占位符表示。模版引擎在解析的時候,會把如數據庫中的或者業余邏輯計算結果填充到這些占位符中。下面先看一個簡單的例子。
我們先建立一個模版文件,Dwoo的模版文件默認是tpl,當然你也可以改為其他文件后綴。模版文件名為knock.tpl,把它保存在template文件夾中,內容為:
- <html>
- <head></head>
- <body>
- <blockquote>
- Knock knock! <br/>
- Who's there? <br/>
- {$name} <br/>
- {$name} who? <br/>
- {$punchline}
- </blockquote>
- </body>
- </html>
可以看到,在Dwoo中,模版文件中,把需要動態更替的內容用{$ }這樣的形式包裹起來,作為占位符,占位符當中的內容到時會被自動更替為實際的內容。接下來看如何使用Dwoo,代碼如下:
- <?php
- include 'dwooAutoload.php';
- // 創建dwoo實例
- $dwoo = new Dwoo();
- //讀取模版文件
- $tpl = new Dwoo_Template_File('tmpl/knock.tpl');
- // 對模版變量賦值
- $data = array();
- $data['name'] = 'Boo';
- $data['punchline'] = 'Don\'t cry, it\'s only a joke';
- // 將實際內容輸出到模版
- $dwoo->output($tpl, $data);
- ?>
下面是使用Dwoo的幾個步驟:
1、首先要包含Dwoo自動裝載類dwooAutoload.php,這個類是自動加載了Dwoo模版所需要的其他依賴的類和工具類;
2、創建Dwoo類的實例;
3、通過new Dwoo_Template_File的方法加載模版,其中的參數為模版文件所在的路徑;
4、設置要向模版文件中輸出的替換內容,在Dwoo中,只需要通過定義一個關聯數組的方法即可,數組中每個元素的名稱跟模版文件中的占位符一一對應,數組中的每個值,就是要替換模版中的實際內容;
5、通過調用output方法,將數據向模版中輸出,傳入的參數為輸出的數組內容和模版路徑。
下圖為輸出結果:
#p#
三、Dwoo語法講解
下面以實例的形式講解下Dwoo的語法,先來看最常用的if語句。
1) if 語句
下面是一個模版的例子:
- <html>
- <head></head>
- <body>
- {if $auth == 0}
- Not logged in
- {else}
- Logged in as: Anonymous User
- {/if}
- </body>
- </html>
可以看到,Dwoo中的if語句其實跟普通的if語句沒什么區別。接下來我們看下控制這個模版的php文件,如下:
- <?php
- include 'dwooAutoload.php';
- try {
- $dwoo = new Dwoo();
- $tpl = new Dwoo_Template_File('tmpl/auth.tpl');
- $data = new Dwoo_Data();
- $data->assign('auth', rand(0,1));
- $dwoo->output($tpl, $data);
- } catch (Exception $e) {
- echo "Error: " . $e->getMessage();
- }
- ?>
注意,這里我們使用了new Dwoo_Data();這個Dwoo_Data()方法的優勢在于,它比較容易存放大量的數據,比用數組的方法去存儲數據方便多了,而且它本身提供了很多不同的方法去獲得,清理和刪除模版變量。這個例子中,用隨機數的方法產生了auth變量,結果可能為如下圖:
當然,可以使用if elseif語句,比如模版中:
- <html>
- <head></head>
- <body>
- {if $auth == 1}
- Logged in as: Anonymous User
- {elseif $auth == 2}
- Logged in as: Administrator
- {else}
- Not logged in
- {/if}
- </body>
- </html>
2) LOOP循環語句
在Dwoo中,可以使用{loop}進行循環,動態產生數據,下面是例子:
- <html>
- <head></head>
- <body>
- <ul>
- {loop $items}
- <li>{escape($item)}</li>
- {/loop}
- </ul>
- </body>
- </html>
下面是產生數據的php文件:
- <?php
- include 'dwooAutoload.php';
- try {
- $dwoo = new Dwoo();
- $tpl = new Dwoo_Template_File('tmpl/list.tpl');
- $data = new Dwoo_Data();
- $items = array();
- $items[] = array('item' => 'red');
- $items[] = array('item' => 'yellow');
- $items[] = array('item' => 'blue');
- $items[] = array('item' => 'green');
- $data->assign('items', $items);
- $dwoo->output($tpl, $data);
- } catch (Exception $e) {
- echo "Error: " . $e->getMessage();
- }
- ?>
這里,我們生成了數組items,然后在模版文件中,通過{loop $items}即可循環輸出內容。結果如下圖:
注意,這里使用了{escape($item)}的方法輸出每一行的內容,其中eascape是dwoo中使用的插件,是將所有內容在輸出前使用HTML編碼格式過濾,這可以防止XSS攻擊,是個很好的實踐。
而在Dwoo中,可以同樣使用{foreach}而達到同樣的效果,代碼如下:
- <html>
- <head></head>
- <body>
- <ul>
- {foreach $items item}
- <li>{escape($item)}</li>
- {/foreach}
- </ul>
- </body>
- </html>
同樣,foreach也可以使用如下的用法,即:
- <html>
- <head></head>
- <body>
- <ul>
- {foreach $items key value}
- <li>{upper($key)} is for {$value}</li>
- {/foreach}
- </ul>
- </body>
- </html>
而配合這個模版,PHP的控制頁面中的關聯數組的寫法如下:
- $data = new Dwoo_Data();
- $items = array(
- 'a' => 'apple',
- 'b' => 'ball',
- 'c' => 'cat',
- 'd' => 'dog'
- );
- $data->assign('items', $items);
這樣輸出結果如下圖:
我們既然學會了loop,下面來嘗試下從數據庫中取出數據集,并通過Dwoo顯示出來,下面是模版文件的主要部分:
- <body>
- <table>
- <tr class="heading">
- <td>Author</td>
- <td>Title</td>
- </tr>
- {loop $records}
- <tr>
- <td>{$author}</td>
- <td>{$title}</td>
- </tr>
- {/loop}
- </table>
- </body>
而PHP文件代碼如下,其中使用了PDO去訪問數據庫:
- <? php
- include 'dwooAutoload.php';
- // 連接數據庫
- try {
- $dbh = new PDO('mysql:dbname=library;host=localhost', 'user', 'pass');
- } catch (PDOException $e) {
- echo "Error: Could not connect. " . $e->getMessage();
- }
- $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- try {
- $sql = "SELECT a.AuthorName AS author, t.TitleName AS title FROM author AS a, title AS t, author_title AS at WHERE a.AuthorID = at.AuthorID AND t.TitleID = at.TitleID ORDER BY author LIMIT 0,20";
- $sth = $dbh->query($sql);
- while ($row = $sth->fetchObject()) {
- $records[] = array('author' => $row->author, 'title' => $row->title);
- }
- //關閉數據庫連接
- unset($dbh);
- $dwoo = new Dwoo();
- $tpl = new Dwoo_Template_File('tmpl/books.tpl');
- $data = new Dwoo_Data();
- $data->assign('records', $records);
- $dwoo->output($tpl, $data);
- } catch (PDOException $e) {
- echo "Error: Could not execute query \"$sql\". " . $e->getMessage();
- unset($dbh);
- } catch (Exception $e) {
- echo "Error: " . $e->getMessage();
- }
- ?>
#p#
四、模版組合
在頁面設計中,常用的最佳實踐是把一個復雜的頁面劃分為不同的部分,同樣模版文件中也應該指定不同的部分,最后再將其組合起來,比如下圖是常件的模版件結構:
可以看到有頭部,尾部和頁面的主體三部分組成,下面給出它們的模版文件header.tpl:
- <!-- BEGIN header.tpl -->
- <html>
- <head></head>
- <body>
- <table width="100%" border="1">
- <tr>
- <td align="center"><a href="#">Home</a></td>
- <td align="center"><a href="#">News</a></td>
- <td align="center"><a href="#">Weather</a></td>
- <td align="center"><a href="#">Hotels</a></td>
- <td align="center"><a href="#">Dining</a></td>
- </tr>
- </table>
- <p />
- <h2>{$title}</h2>
- <p />
- <!-- END header.tpl -->
- footer.tpl
- <!-- BEGIN footer -->
- <table width="100%" align="center">
- <tr>
- <td align="center"><font size="-2">© {$year}. All rights reserved.</font></td>
- </tr>
- </table>
- </body>
- </html>
而Dwoo中,使用include可以將不同的模版包含到同一個模版中去,比如下面是框架主模版文件main.tpl:
- {include(file='header.tpl')}
- <!-- BEGIN main.tpl -->
- <table border="1">
- <tr>
- <td valign="top">
- <strong>{$headline}</strong>
- <p />
- {$content}
- </td>
- <td valign="top" align="center" width="25%">
- <strong>Special Feature</strong><br />
- {$feature}
- </td>
- </tr>
- </table>
- <!-- END main.tpl -->
- {include(file='footer.tpl')}
而框架文件的php文件如下,可以為主框架模版中的變量賦值:
- <?php
- include 'dwooAutoload.php';
- try {
- $dwoo = new Dwoo();
- $tpl = new Dwoo_Template_File('tmpl/main.tpl');
- $data = new Dwoo_Data();
- $data->assign('title', 'Welcome to London!');
- $data->assign('headline', 'Playing in the Park');
- $data->assign('content', 'It\'s a warm summer day, and Simon finds the lake in St. James Park too inviting for words...');
- $data->assign('feature', 'Tower Bridge - Snapshots from the Top');
- $data->assign('year', date('Y', mktime()));
- $dwoo->output($tpl, $data);
- } catch (Exception $e) {
- echo "Error: " . $e->getMessage();
- }
- ?>
可以得出如下結果:
而另外的實現方法,是不使用include,而是在主框架模版中如下設置:
- {$header}
- <!-- BEGIN main.tpl -->
- <table border="1">
- <tr>
- <td valign="top">
- <strong>{$headline}</strong>
- <p />
- {$content}
- </td>
- <td valign="top" align="center" width="25%">
- <strong>Special Feature</strong><br />
- {$feature}
- </td>
- </tr>
- </table>
- <!-- END main.tpl -->
- {$footer}
而在PHP文件中,再動態設置header和footer的變量的值,
- $data->assign('header',$dwoo->get(new Dwoo_Template_File('tmpl/header.tpl'), $data));
- $data->assign('footer',$dwoo->get(new Dwoo_Template_File('tmpl/footer.tpl'), $data));
這里使用了Dwoo中的get方法,將兩個模版文件中的內容提取出來,設置到header和footer兩個變量中去。
#p#
五、Dwoo中的插件機制
在Dwoo中,為開發者提供了大量方便的插件,比如前文提到的escape過濾功能,也是Dwoo 的插件之一。下面再學習一個同樣功能的插件auto_esacpe,它其實實現的是跟escape一樣的功能,但它可以針對一整段的模版變量進行格式化,比如,如下的模版:
- <html>
- <head></head>
- <body>
- {auto_escape on}
- {$html}
- {/auto_escape}
- </body>
- </html>
這里使用了{auto_escape on},表明在 {/auto_escape}前的輸出全部要進行HTML格式化,考察如下的php腳本:
- <?php
- include 'dwooAutoload.php';
- try {
- $dwoo = new Dwoo();
- $tpl = new Dwoo_Template_File('tmpl/out.tpl');
- $data = array();
- $data['html']= '<span id="ack">Welcome to Jack & Jill\'s humble abode.</span>';
- $dwoo->output($tpl, $data);
- } catch (Exception $e) {
- echo "Error: " . $e->getMessage();
- }
- ?>
其輸出為如下圖:
同樣,Dwoo也有象php中的strip_tags方法,用來去掉HTML標記,比如:
- <html>
- <head></head>
- <body>
- {strip_tags($html)}
- </body>
- </html>
對應的PHP腳本為:
- $data = array();
- $data['html'] = '<a href="http://www.google.com">Search</a>';
那么將會輸出如下結果:
下面再介紹Dwoo中關于日期格式化的處理,其中可以使用date_format這個插件,這個插件需要傳入兩個參數,一個是要處理的日期,另外一個是指定用什么格式去格式化處理日期,舉個例子:
- <html>
- <head></head>
- <body>
- {date_format $date "%d.%m.%Y"}
- <br/>
- {date_format $date "%B %d, %Y %I:%M %p"}
- </body>
- </html>
處理的PHP代碼的核心部分:
- $data = array();
- $data['date'] = '14 July 2010 21:35';
下面為其輸出:
小結
在本文中,介紹了PHP模版引擎Dwoo的基本原理和用法,給讀者一個快速的入門,在下一篇中,將深入介紹挖掘Dwoo中的一些特色功能。
【編輯推薦】