將PHP代碼和靜態HTML代碼進行分離,使代碼的可讀性和維護性得到顯著提高。
使用模板引擎:
我們所說的模板是Web模板,是主要由HTML標記組成的語言來編寫的頁面,但也有如何表示包含動態生成內容的方式(解析標籤)。模板引擎是一種軟件庫,允許我們從模板生成HTML代碼,並指定要包含的動態內容。
模板引擎的特點:
1.鼓勵分離:讓更個系統的可讀性和維護性得到提高。
2.促進分工:使得程序員和美工去專心處理自己的設計。
3.比PHP更容易解析:編譯文件和緩存文件加載更快、佔資源更少。
4.增加安全性:可限制模板設計師進行不安全的操作的能力避免誤刪誤訪問等。
模板處理的流程圖
創建模板:
1、創建初始模板所需要的文件夾和文件。
a) index.php主文件,用於編寫業務邏輯。
b) template.inc.php模板初始化文件,用於初始模版信息。
c) templates目錄存放所有的模板文件。
d) templates_c目錄存放所有編譯文件。
e) cache目錄存放所有緩存文件。
f) includes目錄存放所有的類文件。
g) config目錄存放模板系統變量配置文件。
以下是源碼:
主文件 index.php
php //index.php
//設置編碼爲UTF-8
header('Content-Type:text/html;Charset=utf-8');
//網站根目錄
define('ROOT_PATH', dirname(__FILE__));
//存放模板文件夾
define('TPL_DIR', ROOT_PATH.'/templates/');
//編譯文件夾
define('TPL_C_DIR', ROOT_PATH.'/templates_c/');
//緩存文件夾
define('CACHE_DIR', ROOT_PATH.'/cache/');
//定義緩存狀態
define('IS_CACHE',true);
//設置緩存狀態開關
IS_CACHE ? ob_start() : null;
include ROOT_PATH.'/includes/Templates.class.php';
$_name = '方塊李'; $array = array(1,2,3,4,5,6); $_tpl = new Templates(); $_tpl->assign('name', $_name); $_tpl->assign('a', 5>4); $_tpl->assign('array', $array); //顯示 $_tpl->display('index.tpl'); ?>
模板文件 HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
{include
"test.php"} {#}這是一條PHP的註釋,在HTML頁面裏是不顯示的,只會在生成的編譯文件裏顯示{#} 我將被index.php導入 {$name}這個標籤必須經過Parser.class.php這個解析類來解析它1
這裏的內容改變了,爲什麼?
{if
$a} 顯示一號皮膚 {else} 顯示二號皮膚 {/if}
{foreach
$array(key,value)}
{/foreach}
|
模板類:
解析類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
//Parser.class.php class Parser
{ //獲取模板內容 private $_tpl ; //構造方法,初始化模板 public function __construct( $_tplFile ){ //判斷文件是否存在 if (! $this ->_tpl
= file_get_contents ( $_tplFile )){ exit ( 'ERROR:讀取模板出錯!' ); } } //解析普通變量 private function parVar(){ $_pattern = '/\{\$([\w]+)\}/' ; if (preg_match( $_pattern , $this ->_tpl))
{ $this ->_tpl
= preg_replace( $_pattern , "_vars['$1']
?>" , $this ->_tpl); } } //解析IF條件語句 private function parIf(){ //開頭if模式 $_patternIf = '/\{if\s+\$([\w]+)\}/' ; //結尾if模式 $_patternEnd = '/\{\/if\}/' ; //else模式 $_patternElse = '/\{else\}/' ; //判斷if是否存在 if (preg_match( $_patternIf , $this ->_tpl)){ //判斷是否有if結尾 if (preg_match( $_patternEnd , $this ->_tpl)){ //替換開頭IF $this ->_tpl
= preg_replace( $_patternIf , "_vars['$1']){
?>" , $this ->_tpl); //替換結尾IF $this ->_tpl
= preg_replace( $_patternEnd , "" , $this ->_tpl); //判斷是否有else if (preg_match( $_patternElse , $this ->_tpl)){ //替換else $this ->_tpl
= preg_replace( $_patternElse , "" , $this ->_tpl); } } else { exit ( 'ERROR:語句沒有關閉!' ); } } } //解析foreach private function parForeach(){ $_patternForeach = '/\{foreach\s+\$(\w+)\((\w+),(\w+)\)\}/' ; $_patternEndForeach = '/\{\/foreach\}/' ; //foreach裏的值 $_patternVar = '/\{@(\w+)\}/' ; //判斷是否存在 if (preg_match( $_patternForeach , $this ->_tpl)){ //判斷結束標誌 if (preg_match( $_patternEndForeach , $this ->_tpl)){ //替換開頭 $this ->_tpl
= preg_replace( $_patternForeach , "_vars['$1']
as \$$2=>\$$3){?>" , $this ->_tpl); //替換結束 $this ->_tpl
= preg_replace( $_patternEndForeach , "" , $this ->_tpl); //替換值 $this ->_tpl
= preg_replace( $_patternVar , "" , $this ->_tpl); } else { exit ( 'ERROR:Foreach語句沒有關閉' ); } } } //解析include private function parInclude(){ $_pattern = '/\{include\s+\"(.*)\"\}/' ; if (preg_match( $_pattern , $this ->_tpl, $_file )){ //判斷頭文件是否存在 if (! file_exists ( $_file [1])
|| empty ( $_file [1])){ exit ( 'ERROR:包含文件不存在!' ); } //替換內容 $this ->_tpl
= preg_replace( $_pattern , "" , $this ->_tpl); } } //解析系統變量 private function configVar(){ $_pattern = '//' ; if (preg_match( $_pattern , $this ->_tpl, $_file )){ $this ->_tpl
= preg_replace( $_pattern , "_config['$1']
?>" , $this ->_tpl); } } //解析單行PHP註釋 private function parCommon(){ $_pattern = '/\{#\}(.*)\{#\}/' ; if (preg_match( $_pattern , $this ->_tpl)){ $this ->_tpl
= preg_replace( $_pattern , "" , $this ->_tpl); } } //生成編譯文件 public function compile( $_parFile ){ //解析模板變量 $this ->parVar(); //解析IF $this ->parIf(); //解析註釋 $this ->parCommon(); //解析Foreach $this ->parForeach(); //解析include $this ->parInclude(); //解析系統變量 $this ->configVar(); //生成編譯文件 if (! file_put_contents ( $_parFile , $this ->_tpl)){ exit ( 'ERROR:編譯文件生成失敗!' ); } } } |
總結:模板引擎的整個過程:
1、當瀏覽器請求index.php文件時,實例化模板類對像 $_tpl = new Templates();
2、當Templates實例化的時候,生成兩個數組,一個用來存放模板變量,另一個存放系統變量,通過構造方法,判斷文件夾是否存在,同時通過XML文件將系統變量數組初始化
3、通過模板類Templates的注入方法,assign(),將對應模板index.tpl中變量的index.php的內容注入到模板類的私有變量,完成初始化
4、模板類Templates類顯示方法display() 通過實例化解析類Parser,將取到的注入變量通過解析類進行解析(即替換)
5、解析(替換)後,將文件寫入PHP、HTML混全文件
6、通過Templates類的顯示方法將文件輸出:
1、第一次執行顯示方法時,將會把PHP、HTML混合文件,生成純靜態的緩存文件
2、調用緩存文件,顯示頁面
3、當瀏覽器再次調用顯示方法時,首先根據各文件的最後修改時間,判斷是否重新生成緩存文件或直接調用已存在的緩存文件
重點:
1、通過正則表達式進行字符串的替換
2、熟悉OOP