现在离职在家,突然发现没什么事儿做了,就研究研究了smarty,写了一个简单的搜索引擎。包含
assign赋值,display模版解析的方法,
新建一个MyTpl.class.php(其他名称也可以)
代码如下:
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
|
<?php
class
MyTpl{
//初始化函数
function
__construct(
$template_dir
=
'templates/'
,
$compile_dir
=
'templates_c'
){
$this
->template_dir=rtrim(
$template_dir
,
'/'
).
'/'
;
$this
->compile_dir=rtrim(
$compile_dir
,
'/'
).
'/'
;
$this
->tpl_vars=
array
();
}
//赋值函数
function
assign(
$tpl_var
,
$value
=null){
if
(
$tpl_var
!=
''
)
$this
->tpl_vars[
$tpl_var
]=
$value
;
}
//模版解析
function
display(
$fileName
){
$tplFile
=
$this
->template_dir.
$fileName
;
if
(!
file_exists
(
$tplFile
))
return
false;
$comFileName
=
$this
->compile_dir.
'com_'
.
basename
(
$tplFile
).
'.php'
;
if
(!
file_exists
(
$comFileName
)||
filemtime
(
$comFileName
)<
filemtime
(
$tplFile
)){
$repContent
=
$this
->tpl_replace(
file_get_contents
(
$tplFile
));
$handle
=
fopen
(
$comFileName
,
'w+'
);
fwrite(
$handle
,
$repContent
);
fclose(
$handle
);
}
require_once
$comFileName
;
}
//模版替换函数
private
function
tpl_replace(
$content
){
$pattern
=
array
(
'/<\{\s*\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-xff]*)\s*\}>/i'
,
//解析变量
'/<\{\s*if\s*(.+?)\s*\}>(.+?)<\{\s*\/if\s*\}>/ies'
,
//if标签解析
'/<\{\s*else\s*if\s*(.+?)\s*\}>/'
,
//elseif解析
'/<\{\s*else\s*\}>/'
,
//else解析
'/<\{\s*loop\s+\$(\S+)\s+\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*\}>(.+?)<\{\\s*\/loop\s*}>/is'
,
//匹配loop标签
'/<\{\s*loop\s+\$(\S+)\s+\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*=>\s*\$(\S+)\s*\}>(.+?)<\{\s*\/loop\s*\}>/is>/'
,
//遍历loop中的键和值
'/<\{\s*include\s+[\"\']?(.+?)[\"\']?\s*\}>/ie'
,
//匹配include
);
//替换成php
$replacement
=
array
(
'<?php echo $this->tpl_vars["${1}"]?>'
,
//变量替换
'$this->stripvtags(\'<?php if(${1}){?>\',\'${2}<?php}?>\')'
,
'$this->stripvtags(\'<?php } elseif(${1}) { ?>\',"")'
,
'<?php } else { ?>'
,
'<?php foreach($this->tpl_vars["${1}"] as $this->tpl_vars["${2}"]) { ?>${3}<?php } ?>'
,
'<?php foreach($this->tpl_vars["${1}"] as $this->tpl_vars["${2}"]=>$this->tpl_vars["${3}"]){?>$(4)<?php } ?>'
,
'file_get_contents($this->template_dir."${1}")'
);
$repContent
=preg_replace(
$pattern
,
$replacement
,
$content
);
if
(preg_match(
'/<\{([^(\}>)]{1,})\}>/'
,
$repContent
)){
$repContent
=
$this
->tpl_replace(
$repContent
);
}
return
$repContent
;
}
//替换条件语句中对应的值
private
function
stripvtags(
$expr
,
$statement
){
$var_pattern
=
'/\s*\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*/is'
;
$expr
=preg_replace(
$var_pattern
,
'$this->tpl_vars["${1}"]'
,
$expr
);
$expr
=
str_replace
(
"\\\""
,
"\""
,
$expr
);
$statement
=
str_replace
(
"\\\""
,
"\""
,
$statement
);
return
$expr
.
$statement
;
}
}
|
以上很简单,就是赋值,然后做模版解析以后再输出,最复杂的一部分就是正则替换这一部分,写了很久,有时间还是借鉴一下smarty的吧。
接下来就测试一下,新建一个inde.php
1
2
3
4
5
|
require_once
'plugins/MyTpl.class.php'
;
$Tpl
=
new
MyTpl();
$title
=
'第一个标题'
;
$Tpl
->assign(
'title'
,
$title
);
$Tpl
->display(
'index.tpl'
);
|
并且新建templates目录,templates_c目录其他根据实际情况来写,然后在templates中新建一个index.tpl,写上相应的代码,我只是做一个简单的测试,
1
2
3
4
5
6
|
<
html
>
<
head
><
title
><{$title}></
title
></
head
>
<
body
>
<{$title}>
</
body
>
</
html
>
|
然后在浏览器中预览,就可以实现,我写的正则替换里,也包括一个loop的foreach替换标签。大家可以继续扩展完善,我也会继续完善一套自己的模版引擎。
本文转自 3147972 51CTO博客,原文链接:http://blog.51cto.com/a3147972/1253462,如需转载请自行联系原作者