​

 本人第一次在phpchina发表原创帖,如果写的不好,欢迎大家拍砖,下面进入正题!

一.模板语法

在模板里面,是可以直接显示php的变量的,也可以使用if,else,循环等,模板解析函数会将这些变量替换成实际的变量值。

1.设置变量的值

<!-–{eval $_TPL['titles'] = array(’日志’, ‘随便看看’);}–->

表示将$_TPL['titles']变量设置为array(’日志’, ‘随便看看’);


2.变量的显示

直接写变量的名字 $_GET[aa]


3.调用另外一个模板文件进来[模板里面再调用模板]

<!–-{template header}-–>实际上相当于php中的

相当于template(”header”) 即解析/template/default/header.htm文件

4.条件判断 <!–-{if xxx}-–>,<!–-{else}-–>,<!–-{/if}–->类

相当于php的if,else,但一定要<!–{/if}–>结束一个if语句

5.循环 <!–-{loop}–><!–-{/loop}-–>类

<!–-{loop $list $key $value}-–>

  

<!--{/loop}-->

相当于php的foreach($list $key=>$value)


6.在模板写php代码

    <!--{eval php代码;}-->

7.时间处理

    <!--{date('Y-m-d h:i',$time)}-->

8.头像处理

    <!--{avatar($uid, $size='small', $returnsrc = FALSE)}-->  returnsrc为true时返回头像的URL


当然了,以上模板语法可以嵌套,所以这也造成我们看模板文件的复杂性,比如在loop里面会有if,即表示每循环一次都要进行判断;又或者if里面有 loop,即表示只有满足条件了,才会进行循环!

二.模板解析过程

1.在php文件中引入模板如果我们要在一个php文件中载入一个模板直接使用:

  include_once template("模板的名字");

如:我们要在index.php文件中引入首页的模板:

  include_once template("index");


2.模板的载入

上面步骤后php将调用template()函数

函数的原型为


​01​

​function​​ ​​template(​​​​$name​​​​) {​


​02​

​global​​ ​​$_SCONFIG​​​​, ​​​​$_SGLOBAL​​​​;​


​03​

​if​​​​(​​​​$_SGLOBAL​​​​[​​​​'mobile'​​​​]) {​


​04​

​$objfile​​ ​​= S_ROOT.​​​​'./api/mobile/tpl_'​​​​.​​​​$name​​​​.​​​​'.php'​​​​;​


​05​

​if​​ ​​(!​​​​file_exists​​​​(​​​​$objfile​​​​)) {​


​06​

​showmessage(​​​​'m_function_is_disable_on_wap'​​​​);​


​07​

​}​


​08​

​} ​​​​else​​ ​​{​


​09​

​if​​​​(strexists(​​​​$name​​​​,​​​​'/'​​​​)) {​


​10​

​$tpl​​ ​​= ​​​​$name​​​​;​


​11​

​} ​​​​else​​ ​​{​


​12​

​$tpl​​ ​​= ​​​​"template/$_SCONFIG[template]/$name"​​​​;​


​13​

​}​


​14​

​$objfile​​ ​​= S_ROOT.​​​​'./data/tpl_cache/'​​​​.​​​​str_replace​​​​(​​​​'/'​​​​,​​​​'_'​​​​,​​​​$tpl​​​​).​​​​'.php'​​​​;​


​15​

​if​​​​(!​​​​file_exists​​​​(​​​​$objfile​​​​)) {​


​16​

​include_once​​​​(S_ROOT.​​​​'./source/function_template.php'​​​​);​


​17​

​parse_template(​​​​$tpl​​​​);​


​18​

​}​


​19​

​}​


​20​

​return​​ ​​$objfile​​​​;​


​21​

​}​

其流程是先判断是不是wap访问,然后获得模板文件的路径,如果当前模板路径不存在则调用default目录下的同名模板,然后看模板文件缓存里是否存在,存在的话直接调用,否则引入source/function_template.php解析模板! 3.模板的解析 我们可以先看下source/function_template.php这个文件,我加了些注释,相信大家能够看懂


​001​

​/*​


​002​

​[UCenter Home] (C) 2007-2008 Comsenz Inc.​


​003​

​$Id: function_template.php 12678 2009-07-15 03:21:21Z xupeng $​


​004​

​*/​


​005​

​if​​​​(!defined(​​​​'IN_UCHOME'​​​​)) {​


​006​

​exit​​​​(​​​​'Access Denied'​​​​);​


​007​

​}​


​008​

​$_SGLOBAL​​​​[​​​​'i'​​​​] = 0;​


​009​

​$_SGLOBAL​​​​[​​​​'block_search'​​​​] = ​​​​$_SGLOBAL​​​​[​​​​'block_replace'​​​​] = ​​​​array​​​​();​


​010​

​function​​ ​​parse_template(​​​​$tpl​​​​) {​


​011​

​global​​ ​​$_SGLOBAL​​​​, ​​​​$_SC​​​​, ​​​​$_SCONFIG​​​​;​


​012​

​//包含模板​


​013​

​$_SGLOBAL​​​​[​​​​'sub_tpls'​​​​] = ​​​​array​​​​(​​​​$tpl​​​​);​


​014​

​//模板文件​


​015​

​$tplfile​​ ​​= S_ROOT.​​​​'./'​​​​.​​​​$tpl​​​​.​​​​'.htm'​​​​;   ​


​016​

​//模板缓存文件​


​017​

​$objfile​​ ​​= S_ROOT.​​​​'./data/tpl_cache/'​​​​.​​​​str_replace​​​​(​​​​'/'​​​​,​​​​'_'​​​​,​​​​$tpl​​​​).​​​​'.php'​​​​;​


​018​

​//read​


​019​

​//如果模板文件不存在,则调用default下的同名模板​


​020​

​if​​​​(!​​​​file_exists​​​​(​​​​$tplfile​​​​)) {​


​021​

​$tplfile​​ ​​= ​​​​str_replace​​​​(​​​​'/'​​​​.​​​​$_SCONFIG​​​​[​​​​'template'​​​​].​​​​'/'​​​​, ​​​​'/default/'​​​​, ​​​​$tplfile​​​​);​


​022​

​}​


​023​

​//读取模板文件的内容    sreadfile()相当于file_get_contents()​


​024​

​$template​​ ​​= sreadfile(​​​​$tplfile​​​​);​


​025​

​// 如果读取的内容为空则报错,模板文件不存在​


​026​

​if​​​​(​​​​empty​​​​(​​​​$template​​​​)) {​


​027​

​exit​​​​(​​​​"Template file : $tplfile Not found or have no access!"​​​​);​


​028​

​}​


​029​

​//模板  替换<!–{template header}–>这类模板语法,然后使用readtemplate()函数获取其内容​


​030​

​$template​​ ​​= preg_replace(​​​​"/\<\!\-\-\{template\s+([a-z0-9_\/]+)\}\-\-\>/ie"​​​​,​​​​"readtemplate('\\1')"​​​​, ​​​​$template​​​​);​


​031​

​//处理子<span href="tag.php?name=%D2%B3%C3%E6" onclick="tagshow(event)" >页面</span>中的代码​


​032​

​$template​​ ​​= preg_replace(​​​​"/\<\!\-\-\{template\s+([a-z0-9_\/]+)\}\-\-\>/ie"​​​​,​​​​"readtemplate('\\1')"​​​​, ​​​​$template​​​​);​


​033​

​//解析模块调用​


​034​

​$template​​ ​​= preg_replace(​​​​"/\<\!\-\-\{block\/(.+?)\}\-\-\>/ie"​​​​, ​​​​"blocktags('\\1')"​​​​,​​​​$template​​​​);​


​035​

​//解析广告   data/adtpl/ 下的广告页面​


​036​

​$template​​ ​​= preg_replace(​​​​"/\<\!\-\-\{ad\/(.+?)\}\-\-\>/ie"​​​​, ​​​​"adtags('\\1')"​​​​, ​​​​$template​​​​);​


​037​

​//时间处理  调用sgmdate()函数格式化时间​


​038​

​$template​​ ​​= preg_replace(​​​​"/\<\!\-\-\{date\((.+?)\)\}\-\-\>/ie"​​​​, ​​​​"datetags('\\1')"​​​​,​​​​$template​​​​);​


​039​

​//头像处理  调用avatar()函数获取头像的url​


​040​

​$template​​ ​​= preg_replace(​​​​"/\<\!\-\-\{avatar\((.+?)\)\}\-\-\>/ie"​​​​, ​​​​"avatartags('\\1')"​​​​,​​​​$template​​​​);​


​041​

​//<span href="tag.php?name=PHP" onclick="tagshow(event)" >PHP</span>代码  处理语法<!--{eval echo X_VER;}--> 标签里的php代码​


​042​

​$template​​ ​​= preg_replace(​​​​"/\<\!\-\-\{eval\s+(.+?)\s*\}\-\-\>/ies"​​​​, ​​​​"evaltags('\\1')"​​​​,​​​​$template​​​​);​


​043​

​//开始处理​


​044​

​//变量 获取变量并对其',"进行转义​


​045​

​$var_regexp​​ ​​= ​​​​"(([url=]\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\[/url]])*)"​​​​;​


​046​

​$template​​ ​​= preg_replace(​​​​"/\<\!\-\-\{(.+?)\}\-\-\>/s"​​​​, ​​​​"{\\1}"​​​​, ​​​​$template​​​​);​


​047​

​$template​​ ​​= preg_replace(​​​​"/([\n\r]+)\t+/s"​​​​, ​​​​"[url=file://\\1]\\1[/url]"​​​​, ​​​​$template​​​​);​


​048​

​$template​​ ​​= preg_replace(​​​​"/([url=]\\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\.([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/s[/url]"​​​​, ​​​​"[url=file://\\1[]\\1['\\2'[/url]]"​​​​, ​​​​$template​​​​);​


​049​

​$template​​ ​​= preg_replace(​​​​"/\{([url=]\\\$[a-zA-Z0-9_\[\]\'\"\$\.\x7f-\xff]+)\}/s[/url]"​​​​,​​​​"<?=\\1?>"​​​​, ​​​​$template​​​​);​


​050​

​$template​​ ​​= preg_replace(​​​​"/$var_regexp/es"​​​​, ​​​​"addquote('<?=\\1?>')"​​​​, ​​​​$template​​​​);​


​051​

​$template​​ ​​= preg_replace(​​​​"/\<\?\=\<\?\=$var_regexp\?\>\?\>/es"​​​​, ​​​​"addquote('<?=\\1?>')"​​​​,​​​​$template​​​​);​


​052​

​//逻辑  替换if,else​


​053​

​$template​​ ​​= preg_replace(​​​​"/\{elseif\s+(.+?)\}/ies"​​​​, ​​​​"stripvtags('<?php } elseif([url=file://\\1]\\1[/url]) { ?>','')"​​​​, ​​​​$template​​​​);​


​054​

​$template​​ ​​= preg_replace(​​​​"/\{else\}/is"​​​​, ​​​​"<?php } else { ?>"​​​​, ​​​​$template​​​​);​


​055​

​//循环  替换loop循环​


​056​

​for​​​​(​​​​$i​​ ​​= 0; ​​​​$i​​ ​​< 6; ​​​​$i​​​​++) {​


​057​

​$template​​ ​​= preg_replace(​​​​"/\{loop\s+(\S+)\s+(\S+)\}(.+?)\{\/loop\}/ies"​​​​, ​​​​"stripvtags('<?php if(is_array([url=file://\\1]\\1[/url])) { foreach([url=file://\\1]\\1[/url] as [url=file://\\2]\\2[/url]) { ?>','\\3<?php } } ?>')"​​​​, ​​​​$template​​​​);​


​058​

​$template​​ ​​= preg_replace(​​​​"/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}(.+?)\{\/loop\}/ies"​​​​,​​​​"stripvtags('<?php if(is_array([url=file://\\1]\\1[/url])) { foreach([url=file://\\1]\\1[/url] as [url=file://\\2]\\2[/url] => [url=file://\\3]\\3[/url]) { ?>','\\4<?php } } ?>')"​​​​, ​​​​$template​​​​);​


​059​

​$template​​ ​​= preg_replace(​​​​"/\{if\s+(.+?)\}(.+?)\{\/if\}/ies"​​​​, ​​​​"stripvtags('<?php if([url=file://\\1]\\1[/url]) { ?>','\\2<?php } ?>')"​​​​, ​​​​$template​​​​);​


​060​

​}​


​061​

​//常量​


​062​

​$template​​ ​​= preg_replace(​​​​"/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/s"​​​​, ​​​​"<?=\\1?>"​​​​,​​​​$template​​​​);​


​063​

 


​064​

​//替换​


​065​

​if​​​​(!​​​​empty​​​​(​​​​$_SGLOBAL​​​​[​​​​'block_search'​​​​])) {​


​066​

​$template​​ ​​= ​​​​str_replace​​​​(​​​​$_SGLOBAL​​​​[​​​​'block_search'​​​​], ​​​​$_SGLOBAL​​​​[​​​​'block_replace'​​​​],​​​​$template​​​​);​


​067​

​}​


​068​

 


​069​

​//换行​


​070​

​$template​​ ​​= preg_replace(​​​​"/ \?\>[\n\r]*\<\? /s"​​​​, ​​​​" "​​​​, ​​​​$template​​​​);​


​071​

 


​072​

​//附加处理​


​073​

​$template​​ ​​= ​​​​"<?php if(!defined('IN_UCHOME')) exit('Access Denied');?><?php subtplcheck('"​​​​.implode('|​​​​', $_SGLOBAL['​​​​sub_tpls​​​​'])."'​​​​, ​​​​'$_SGLOBAL[timestamp]'​​​​, ​​​​'$tpl'​​​​);?>​​​​$template​​​​<?php ob_out();?>";​


​074​

 


​075​

​//write  写入模板缓存​


​076​

​if​​​​(!swritefile(​​​​$objfile​​​​, ​​​​$template​​​​)) {​


​077​

​exit​​​​(​​​​"File: $objfile can not be write!"​​​​);​


​078​

​}​


​079​

​}​


​080​

​//转义函数​


​081​

​function​​ ​​addquote(​​​​$var​​​​) {​


​082​

​return​​ ​​str_replace​​​​(​​​​"[url=]\\\[/url]"​​​​", "​​​​\​​​​""​​​​, preg_replace(​​​​"/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s"​​​​, ​​​​"['\\1']"​​​​, ​​​​$var​​​​));​


​083​

​}​


​084​

​function​​ ​​striptagquotes(​​​​$expr​​​​) {​


​085​

​$expr​​ ​​= preg_replace(​​​​"/\<\?\=([url=]\\\$.+?)\?\>/s[/url]"​​​​, ​​​​"[url=file://\\1]\\1[/url]"​​​​,​​​​$expr​​​​);​


​086​

​$expr​​ ​​= ​​​​str_replace​​​​(​​​​"[url=]\\\[/url]"​​​​", "​​​​\​​​​""​​​​, preg_replace(​​​​"/\[\'([a-zA-Z0-9_\-\.\x7f-\xff]+)\'\]/s"​​​​, ​​​​"[\\1]"​​​​, ​​​​$expr​​​​));​


​087​

​return​​ ​​$expr​​​​;​


​088​

​}​


​089​

​//处理变量​


​090​

​function​​ ​​evaltags(​​​​$php​​​​) {​


​091​

​global​​ ​​$_SGLOBAL​​​​;​


​092​

​$_SGLOBAL​​​​[​​​​'i'​​​​]++;​


​093​

​$search​​ ​​= ​​​​"<!--EVAL_TAG_{$_SGLOBAL['i']}-->"​​​​;​


​094​

​$_SGLOBAL​​​​[​​​​'block_search'​​​​][​​​​$_SGLOBAL​​​​[​​​​'i'​​​​]] = ​​​​$search​​​​;​


​095​

​$_SGLOBAL​​​​[​​​​'block_replace'​​​​][​​​​$_SGLOBAL​​​​[​​​​'i'​​​​]] = ​​​​"<?php "​​​​.stripvtags(​​​​$php​​​​).​​​​" ?>"​​​​;​


​096​

 


​097​

​return​​ ​​$search​​​​;​


​098​

​}​


​099​

​//处理模块调用​


​100​

​function​​ ​​blocktags(​​​​$parameter​​​​) {​


​101​

​global​​ ​​$_SGLOBAL​​​​;​


​102​

​$_SGLOBAL​​​​[​​​​'i'​​​​]++;​


​103​

​$search​​ ​​= ​​​​"<!--BLOCK_TAG_{$_SGLOBAL['i']}-->"​​​​;​


​104​

​$_SGLOBAL​​​​[​​​​'block_search'​​​​][​​​​$_SGLOBAL​​​​[​​​​'i'​​​​]] = ​​​​$search​​​​;​


​105​

​$_SGLOBAL​​​​[​​​​'block_replace'​​​​][​​​​$_SGLOBAL​​​​[​​​​'i'​​​​]] = ​​​​"<?php block(\"$parameter\"); ?>"​​​​;​


​106​

​return​​ ​​$search​​​​;​


​107​

​}​


​108​

​//处理广告调用​


​109​

​function​​ ​​adtags(​​​​$pagetype​​​​) {​


​110​

​global​​ ​​$_SGLOBAL​​​​;​


​111​

​$_SGLOBAL​​​​[​​​​'i'​​​​]++;​


​112​

​$search​​ ​​= ​​​​"<!--AD_TAG_{$_SGLOBAL['i']}-->"​​​​;​


​113​

​$_SGLOBAL​​​​[​​​​'block_search'​​​​][​​​​$_SGLOBAL​​​​[​​​​'i'​​​​]] = ​​​​$search​​​​;​


​114​

​$_SGLOBAL​​​​[​​​​'block_replace'​​​​][​​​​$_SGLOBAL​​​​[​​​​'i'​​​​]] = ​​​​"<?php adshow('$pagetype'); ?>"​​​​;​


​115​

​return​​ ​​$search​​​​;​


​116​

​}​


​117​

​//格式化时间​


​118​

​function​​ ​​datetags(​​​​$parameter​​​​) {​


​119​

​global​​ ​​$_SGLOBAL​​​​;​


​120​

​$_SGLOBAL​​​​[​​​​'i'​​​​]++;​


​121​

​$search​​ ​​= ​​​​"<!--DATE_TAG_{$_SGLOBAL['i']}-->"​​​​;​


​122​

​$_SGLOBAL​​​​[​​​​'block_search'​​​​][​​​​$_SGLOBAL​​​​[​​​​'i'​​​​]] = ​​​​$search​​​​;​


​123​

​$_SGLOBAL​​​​[​​​​'block_replace'​​​​][​​​​$_SGLOBAL​​​​[​​​​'i'​​​​]] = ​​​​"<?php echo sgmdate($parameter); ?>"​​​​;​


​124​

​return​​ ​​$search​​​​;​


​125​

​}​


​126​

​//头像处理​


​127​

​function​​ ​​avatartags(​​​​$parameter​​​​) {​


​128​

​global​​ ​​$_SGLOBAL​​​​;​


​129​

​$_SGLOBAL​​​​[​​​​'i'​​​​]++;​


​130​

​$search​​ ​​= ​​​​"<!--AVATAR_TAG_{$_SGLOBAL['i']}-->"​​​​;​


​131​

​$_SGLOBAL​​​​[​​​​'block_search'​​​​][​​​​$_SGLOBAL​​​​[​​​​'i'​​​​]] = ​​​​$search​​​​;​


​132​

​$_SGLOBAL​​​​[​​​​'block_replace'​​​​][​​​​$_SGLOBAL​​​​[​​​​'i'​​​​]] = ​​​​"<?php echo avatar($parameter); ?>"​​​​;​


​133​

​return​​ ​​$search​​​​;​


​134​

​}​


​135​

​function​​ ​​stripvtags(​​​​$expr​​​​, ​​​​$statement​​​​=​​​​''​​​​) {​


​136​

​$expr​​ ​​= ​​​​str_replace​​​​(​​​​"[url=]\\\[/url]"​​​​", "​​​​\​​​​""​​​​, preg_replace(​​​​"/\<\?\=([url=]\\\$.+?)\?\>/s[/url]"​​​​, ​​​​"[url=file://\\1]\\1[/url]"​​​​, ​​​​$expr​​​​));​


​137​

​$statement​​ ​​= ​​​​str_replace​​​​(​​​​"[url=]\\\[/url]"​​​​", "​​​​\​​​​""​​​​, ​​​​$statement​​​​);​


​138​

​return​​ ​​$expr​​​​.​​​​$statement​​​​;​


​139​

​}​


​140​

​//获取子模板的内容​


​141​

​function​​ ​​readtemplate(​​​​$name​​​​) {​


​142​

​global​​ ​​$_SGLOBAL​​​​, ​​​​$_SCONFIG​​​​;​


​143​

 


​144​

​$tpl​​ ​​= strexists(​​​​$name​​​​,​​​​'/'​​​​)?​​​​$name​​​​:​​​​"template/$_SCONFIG[template]/$name"​​​​;​


​145​

​$tplfile​​ ​​= S_ROOT.​​​​'./'​​​​.​​​​$tpl​​​​.​​​​'.htm'​​​​;​


​146​

 


​147​

​$_SGLOBAL​​​​[​​​​'sub_tpls'​​​​][] = ​​​​$tpl​​​​;​


​148​

 


​149​

​if​​​​(!​​​​file_exists​​​​(​​​​$tplfile​​​​)) {​


​150​

​$tplfile​​ ​​= ​​​​str_replace​​​​(​​​​'/'​​​​.​​​​$_SCONFIG​​​​[​​​​'template'​​​​].​​​​'/'​​​​, ​​​​'/default/'​​​​, ​​​​$tplfile​​​​);​


​151​

​}​


​152​

​$content​​ ​​= sreadfile(​​​​$tplfile​​​​);​


​153​

​return​​ ​​$content​​​​;​


​154​

​}​


​155​

​?>​

解析完模板后在将其保存在模板缓存里供下次利用!

总结:我个人觉得uchome的模板引擎还是很简洁高效的,而且基本能满足模板的用法需要,实现美工和程序的分工!另外每次解析后以php文件的形式缓存起来,大大增加了其运行效率!

写这个帖子是因为我觉得这套模板引擎完全可以放到其他项目使用,希望对大家有帮助!