程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 【PHP 模板引擎】Prototype 原型版發布!,prototype原型

【PHP 模板引擎】Prototype 原型版發布!,prototype原型

編輯:關於PHP編程

【PHP 模板引擎】Prototype 原型版發布!,prototype原型


在文章的開頭,首先要向一直關注我的人說聲抱歉!因為原本是打算在前端框架5.0發布之後,就立馬完成 PHP 模板引擎的初版。但我沒能做到,而且一直拖到了15年元旦才完成,有很嚴重的拖延症我很慚愧,再次抱歉!

之前有說過以後的作品發布文章都會同步發表相應的 API 使用說明,但我覺得這還不夠好而且博客平台對表格的處理和顯示不是很友好,導致 API 不能完美的呈現,因此打算只提供 API 鏈接,大家可以通過鏈接直接訪問到我的官網去查閱手冊,那樣的閱讀體驗是最好的。而發布的文章以後則更新一些和 API 相關的使用教導,提供一些小例子,讓大家在閱讀 API 的同時,也能夠通過實際例子去更加深刻的體會到代碼的各種用法與業務邏輯思想!

 

以下是 API 手冊與實例演示鏈接

【實例演示】:http://www.shibuyi.net/demo/php/template_engine/prototype

【官方 API 使用手冊】:http://www.shibuyi.net/api/php/template_engine/prototype

【筆者個人官網】:http://www.shibuyi.net

 

 

下面為 PHP 模板引擎 Prototype 原型版使用教導,以下直接簡稱:模板引擎!

什麼?不知道模板引擎是啥?可能會有 PHP 新手會問這樣的問題,那我就簡單的回答一下吧。模板引擎其實就是 PHP 的一個中間件技術,讓傳統的 Web 動態網站編程變得更加輕松,為什麼這麼說呢?以前不輕松嗎?那是因為在模板引擎出現之前,幾乎所有的 Web 服務端程序員都是通過混編代碼完成工作的,所謂混編就是一張頁面中既包含:PHP 也包含 HTML 甚至還有其他語言的代碼,因此項目如果逐漸擴展,開發和維護的時間成本是極高的,還容易出錯,美工與程序也不好配合,如果美工一點也不理解程序,那基本上沒辦法看混編文件。而模板引擎的誕生就很好的解決了這一難題。它采用模板引擎技術將混編文件中的 PHP 業務邏輯層代碼與表現層代碼 HTML 進行了很好的切割分離,程序員則可以安心的設計程序,而美工則安心的設計界面,二者之間會使用一種模板標記的特殊符號進行關聯,方便模板引擎讀取模板文件之後可以順利的進行編譯操作。市面上 PHP 已經有很多相當成熟的模板引擎了,如:Smarty 模板引擎等等,其他 Web 服務端語言也有自己相應的模板引擎,或者與模板引擎類似的中間件技術。

關於模板引擎的詳細介紹,推薦大家訪問百度百科:http://baike.baidu.com/view/4258079.htm

在學習模板引擎之前大家要先保證自己已經了解了 PHP 的 OOP(面向對象編程)思想,因為模板技術是采用 OOP 思想描述的,如果不懂 OOP 那麼這篇文章就不適合您閱讀,因為門檻過高!

 

首先大家看到的圖片是模板引擎的目錄結構圖(筆者使用的是 ZendStudio 7.2.1 集成開發環境):

1. caches 為模板緩存目錄(若不存在模板引擎第一次執行會自動生成);

2. classes 為模板引擎核心類庫;

3. compiles 為模板編譯目錄(若不存在模板引擎第一次執行會自動生成);

4. constants 為模板常量目錄(若不存在模板引擎第一次執行會自動生成);

5. includes 為模板配置目錄;

6. templates 為模板文件目錄(若不存在模板引擎第一次執行會自動生成)。

 

在了解了模板引擎的目錄後,接下來我們就來看看如何讓他運作起來。在原型版中模板引擎的相關初始化和配置信息都是在 includes/template.inc.php 文件中完成的(大家可以打開源碼進行查閱)。

其實對模板引擎的配置又叫做初始化過程,初始化的第一步就是配置相應的目錄,讓模板引擎能夠正確的讀取和寫入該目錄中的數據(配置步驟大家可以自由選擇,不一定非要按照我的順序來配置,但一定要在實例化模板引擎之前完成,否則將會失效),而我們則假設與模板引擎在同一目錄下進行配置,如果非同一目錄對於根目錄的配置需要注意調整。

 

1. 首先第一步是配置模板引擎的根目錄,如果不設置則會自動生成根目錄的絕對路徑。

Template :: $rootPath = dirname(__FILE__); // 相對與絕對路徑均可,我們這裡則采用絕對路徑!如:"C:/wwwroot/prototype"

 

2. 配置模板文件目錄,這個目錄是用來存放模板文件的,如果不設置則默認為:templates 目錄。

// 這裡則采用默認目錄,大家根據自己的需求進行設置,建議不要寫中文容易出錯,目錄名的前後加不加正反斜槓都無所謂,最終模板引擎內部會自動校正!
Template :: $templateName = '/templates/';

 

3. 配置編譯文件目錄,這是用來存在模板文件被解析後生成的編譯文件,如果不設置則默認為:compiles 目錄。

Template :: $compileName = '/compiles/'; // 和模板目錄一樣也采用默認目錄。

 

4. 配置緩存文件目錄,這是在模板引擎開啟緩存功能後,用來存在編譯文件生成的緩存文件,如果不設置默認為:caches 目錄。

Template :: $cacheName = '/caches/'; // 一樣使用默認

 

5. 配置模板常量目錄,可能大家不太理解模板常量是用來干嘛的,和普通的PHP常量有什麼區別嗎?關於模板常量的解釋,在接下來的運用在我們在詳細探討,這裡就先跟我進行配置即可,如果不設置默認為:constants 目錄。

Template :: $constantName = '/constants/'; // 使用默認

 

6. 到第六步為止,目錄的配置就全部完成了,大家不用擔心目錄不存在的問題,也不用手動去創建,模板引擎內部會自動幫我們完成。那麼接下來就是設置模板常量的文件名稱,如果不設置則默認為:default.xml 文件。

// 我們也采用默認,但大家要注意的是這裡必須采用 .xml 為擴展名,因為常量文件是以 XML 標記描述的,如果不是 .xml 結尾,那麼可能會導致模板引擎在處理常量時出現異常情況!
Template :: $constantFile = 'default.xml';

 

7. 設置緩存開關,緩存默認情況下是被關閉的,只有我們去設置他,才會開啟。

// 大家注意,這裡我寫的是一個布爾值,其實這裡可以填寫任意值,最終都會被隱式轉換為布爾值,寫 0 或 1 都可以,我直接寫布爾值是為了方便大家的理解!
Template :: $cacheSwitch = true;

 

8. 至此模板引擎的配置基本上就已經全部完成了,還是很簡單的。現在我們只需要實例化出模板引擎對象,就可以真正的運行模板引擎了。

$tpl = new Template(); // 實例化出模板引擎,從這一步開始之前的配置全部生效,模板引擎實例化時不需要傳遞任何參數。

 

9. 在實例化出模板引擎對象以後,我們就可以開始對其進行操作,那麼對誰進行操作呢?當然是模板文件了,首先我們要先創建模板文件。在模板文件目錄中進行創建。模板文件其實是純 HTML 代碼文件,擴展名可以自定義,而我們約定俗成,都已 .tpl 為擴展名。假設我們已經創建了一個模板文件名為:index.tpl,因為和我們的 php 業務邏輯文件 index.php 同名,這也是按照慣例約定俗成,因為 index.php 文件調用 index.tpl 模板,見名知意。

 

10. 在創建了模板文件之後,我們就可以在業務文件(之前的配置也都是在 index.php 中執行的)中進行對模板文件的加載以及注入模板變量,關於模板變量和其他的模板標識符(又統稱模板標記)將在接下來的步驟中逐一講解。

// 注入變量的格式有兩種,大家注意看 API 手冊的說明,數組格式與傳統的鍵值對格式均可以,我們兩種都使用一下。
$tpl -> assign('title', '頭銜'); // 首先是傳統鍵值對格式

$tpl -> assign(array('title' => '頭銜', 'name' => '名稱')); // 數組格式明顯要更加好用一些,因為在注入多個變量時,就可以不用寫多個注入語句,一句話就搞定了。

// 如果出現了兩個一模一樣的變量名稱,那麼其後會將之前的給替換掉。以下代碼,最終 language 變量的值為:英文。
$tpl -> assign(array('language' => '中文', 'language' => '英文'));

// 接下來是加載模板文件,直接寫模板名稱即可,模板引擎會自動鎖定到模板文件目錄。
$tpl -> display('index.tpl');

 

11. 至此對模板引擎的操作就結束了,接下來我們將熟悉一下模板文件中的各個模板標記的使用方法,他們都是用來做什麼的。在原型版中模板標記一共有 9 種,分別為:1. 模板變量、2. 模板常量、3. 單行模板注釋、4. 多行模板注釋、5. include 文件加載、6. template 模板文件加載、7. source 源模板文件加載(較為特殊)、8. if 分歧語句、9. foreach 循環語句。那麼我們首先解釋一下模板變量吧。

<div id="main">
    <!-- 剛剛我們注入了 title 變量,那麼模板在模板文件中就可以對其進行調用了,調用方法就是保持同名,按著這樣的格式抒寫即可{$模板變量名稱}-->
    <!-- 模板變量的命名規范與 PHP 普通變量一模一樣,首位不能為數字,且區分大小寫,注意保證格式的正確性,如果錯誤模板引擎將不會對其進行解析 -->
    <a href="###">{$title}</a> <!-- 正確的格式,被正確解析 -->
    <a href="###">{$123}</a> <!-- 錯誤的格式,無法解析 -->
</div>

 

12. 下面是模板常量的使用,模板常量和 PHP 常量雖然名字上都叫他常量,其實本質上並非一回事。模板常量其實看以看做是偽常量,而並非真正的常量,他是通過對 XML 標記的處理,來保持一組特定不變的值,這些值需要手動的添加到常量文件中。(手動添加其實不太方便,筆者會在其後的版本迭代中,加入自動添加的功能)

首先我們需要在模板常量文件中手動添加模板常量,代碼如下:

<?xml version="1.0" coding="utf-8" ?>
<root>
    <!-- 必須在 root 根標記中間進行添加,而且一個標記字母都不能出錯,注意區分大小寫,如果不慎寫錯,模板引擎將無法對其進行獲取 -->
    <constant>
        <key>WEBNAME</key> <!-- 這裡填寫常量名稱注意字母必須全部大寫,第一位不能為數字,格式與 PHP 定義常量一樣 -->
        <value>網站標題</value> <!-- 值可以為空 -->
    </constant>
    
    <constant>
        <key>123abc</key> <!-- 錯誤的常量名 -->
        <value></value> <!-- 空值 -->
    </constant>
</root>

 配置好常量後,接下來就是在模板文件中進行調用,代碼如下:

<!-- 模板常量的調用和變量類似,只是取消了 $ 符號,另外常量名要保持一致 -->
<title>{WEBANME}</title> <!-- 正確的名稱,將被正確解析 -->
<p>{NAME}</p> <!-- 雖然格式正確,但剛才沒有進行 NAME 常量的配置,因此最終解析後會返回一個空值 -->
<p>{abc123}</p> <!-- 錯誤的名稱,無法解析 -->

 

13. 下面是模板的注釋符,有兩種:一種為單行,一種為多行。多用於對模板文件代碼的注解,可以讓美工配合設計界面的時候了解代碼的實際含義。

<!-- 大家可以把模板注釋放到 HTML 注釋中,這樣美工在設置模板頁面的時候會更加一目了然。-->
<!-- 單行注釋的格式是:{@}內容可寫可不寫,但不寫也就沒有意義了 -->
{@ 普通的單行注釋} <!-- 正確的格式 -->
<!-- {@ HTML 代碼中的單行注釋} --> <!-- 正確的格式 -->
{@ 換行的
單行注釋} <!-- 格式錯誤,單行注釋無法換行,模板引擎無法解析 -->

<!-- 多行注釋的格式是:{#}...{/#}一頭一尾要呼應,內容也可以不寫 -->
{#}這是多行行注釋,注意首位呼應!{/#} <!-- 正確的格式 -->
{#}這是多行行注釋,
我換行了!{/#} <!-- 正確的格式 -->
{#} 沒有寫結尾符號 <!-- 錯誤的格式,模板引擎無法解析 -->

 

14. 模板加載標識符,加載方式分為三類,別分為:include 對普通文件的直接加載;template 對模板文件進行編譯後加載;source 對模板文件進行編譯後直接輸出編譯文件的路徑(此方法較為特殊且並不完美,需要在特定的場合中使用,比如:框架頁面的調用)

首先是對普通文件的加載調用,代碼如下:

<!-- 注意抒寫格式,被直接加載的文件多半是 php 文件,且文件必須要存在,不存在的文件,模板引擎將會給出一個錯誤提示,並且終止代碼的執行 -->
<!-- 文件名前後的引號,單雙引號都可以,但必須保持一致,不能一單一雙,否則模板引擎將不會對其解析 -->
{include path = "test.php"} <!-- 正確的格式,將被解析 -->
{include path = 'abc.php"} <!-- 錯誤的格式,無法被解析 -->
<!-- 如果出現了同一個文件被加載了兩次,那麼模板引擎只會對其加載第一次後,自動忽略其後的加載 -->
{include path = "123.php"} <!-- 第一次被加載成功 -->
{include path = "123.php"} <!-- 與上一個文件同屬一個文件,將無法被再次加載,而被自動忽略 -->

下面是對模板文件的編譯加載,代碼如下:

<!-- 格式與 include 方式基本一樣,就不重復闡述了,不一樣的是 include 是需要給出具體的路徑地址,而 template 則只需要給出模板名稱即可,模板引擎會自動找到該模板文件 -->
{template path = 'test.tpl'} <!-- 正確的格式,將會被編譯後加載 -->

最後就是模板文件的編譯地址的輸出,該功能較特殊,即使不理解也沒關系,該方法有嚴重的 BUG 尚未處理完畢,因此並不完美,且使用的概率也極低,這裡只做簡單的介紹。在其後的版本迭代中,是否會保留並完善,尚在定奪,代碼如下:

<!-- 這裡我們將使用 iframe 框架頁面,來調用 source 加載方法,調用格式與前兩種雷同,就不在闡述 -->
<!-- 這樣使用其實就可以了,但又嚴重的 BUG 出現,原因是所有在 frame.tpl 中注入的模板標記被解析後,將無法找到源頭,也就是說 php 將無法對其正確處理,並且因為無法找到源頭,而會報錯,該 BUG 的解決方案還在研究中,這裡僅提供給大家思考 -->
<iframe src="{source path = 'frame.tpl'}"></iframe>

 

15. 接下來是經常會被用到的 if 分歧語句,他和 php 的 if 語句很類似,但功能上卻很簡單,且不支持多重判斷以及嵌套判斷,但我會在其後的版本迭代中讓其功能逐步強大。

<!-- if 語句的格式其實和多行注釋一樣,一定要注意首位呼應,但大小寫無所謂都能夠支持和 PHP 原生的 if 語句是一樣的。 -->
{if $action} <!-- 只要被注入的 {$action} 變量的值為 true,或隱式轉換後為 true,那麼 if 語句中的代碼將被顯示 -->
<p>界面1</p>
{/if}

{if !$action} <!-- 加入了邏輯非的判斷,只要為 false 則被顯示 -->
<p>界面2</p>
{/if}

{if $action} <!-- 雙層判斷的時候,為 true 時顯示界面1,為 false 時顯示界面2 -->
<p>界面1</p>
{else}
<p>界面2</p>
{/if}

{if $action} <!-- 錯誤的格式,沒有結尾,不會被模板引擎解析 -->

 

16. 終於到了最後的也是復雜的 foreach 循環語句的調用了,其功能和 PHP 一樣,只是格式上稍有改動。

<!-- 注意在調用 foreach 和 if 一樣要收尾呼應,而且如果變量不是數組格式,那麼 php 將會自動報出一個錯誤 -->
<!-- 其中 $array 就是被注入的模板變量,注意要是數組格式;而 key 和 value 則是對於的數組中的鍵值對,必須寫,否則格式不正確,將無法被模板引擎解析 -->
{foreach $array(key, value)}
    <p>{%key} ... {%value}</p> <!-- 注意 key 和 value 可以自定義,但一定要同名調用,否則無法被解析 -->
{/foreach}

{foreach $userList(id, username)}
    <p>{%id} ... {%username}</p> <!-- 自定義的 key 和 value,格式正確 -->
    <p>{%password}</p> <!-- 錯誤的格式,並沒有被定義,因此無法被解析 -->
{/foreach}

 

好了,寫到這裡我也可以長長的舒口氣,模板引擎原型版的教導到此就結束了。雖然教導文章已經很詳細了,但建議大家配合 API 手冊和實例代碼進行參照閱讀,這樣效果會更好更便於理解和掌握。當然因為是文章,所以即使你描述的再詳細,文字也是抽象的,需要大家多動手,而對於動手能力較差的新手們,這篇教導文章則起不到多大的作用,可能反而會被弄得一頭霧水,甚至最終對此厭惡,所以我有想過如果以後有可能,在版本迭代更新到一定程度後,我會針對性的出一套系列教導視頻,那樣的話就不會像文字這樣抽象,新手也能夠很快的學習。

 

如果你是從頭看到尾,那麼我真心感謝您的閱覽,我想你應該有什麼話要想說,請一定要在下面留言告訴我,有問題也請及時留言,謝謝各位的支持~!

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved