您的位置:首页 > 其它

自行开发的 轻量级 模板引擎

2013-12-23 08:53 141 查看
模板的作用:表现与实现相分离.

项目中考虑 Smarty或其它模板引擎,过于庞大,功能较多,但项目中使用的较少.

另外,模板语法过于复杂,增加了开发人员的学习成本.

故,自行开发了一个小模板引擎,实现了编译及缓存功能.

代码如下:

<?php
/**
* 模板类
一.for循环
<for($i=0;$i<count($arr);$i++)>
<endfor>
缺陷:如表达式中有>(大于号),将导致视图在DW中出现多余字符
二.foreach循环
<foreach($arr as $k=>$v)>
<endforeach>
缺陷:'=>' 将导致视图在DW中出现多余字符
三.if判断
<if($i>5)>
<elseif($i>2)>
<else>
<endif>
缺陷:如果表达式中有>(大于号),将导致视图在DW中出现多余字符
四.嵌套原生代码
<php>
</php>
五.子模板包含
<include('子模板',参数数组)>
注意:紧密连接
六.自我感知
<model(结果变量名 模型类名 方法(参数表))>
注意:这个与PHP语法实在无法一致了,中间是空格分开的,此句等同于 <?php $结果变量名=模型类名::instance()->方法(参数表) ?>
七.显示函数返回值
{date('Y-m-d H;i:s')}
注意:既然是函数调用,最后就应该是')'结束
八.显示变量的值
{$变量}
{$对象.属性}
{$数组[下标]}
九.赋值
<assign($变量=表达式)>

全局注意:
'<for(',')>' 以及 '<endfor>' 必须紧密连接
'<foreach(',')>'以及'<endforeach>' 必须紧密连接
其它标签也是如此
*/
class STemplate{

/**
* 显示视图,如果需要,智能编译
*
* @param string $view 视图
* @param array $params 参数
*/
static public function display($view,$params){
extract($params);
include(self::getTpl($view));
}

/**
* 根据视图获取编译后的模板文件,会自动进行智能编译
*
* @param string $view 视图
* @return string 模板文件(带路径)
*/
static private function getTpl($view){
$source=SConfig::system('dir_view').$view.'.'.SConfig::system('suffix_view');
$target=SConfig::system('dir_template').$view.'.'.SConfig::system('suffix_template');
if(!file_exists($source)){
throw new Exception('View file not exist:'.$view);
}

//调试模式 或 缓存文件不存在 或 缓存文件过期 则:重新编译
if(!file_exists($target) or filemtime($source)>filemtime($target)){
$dirs=explode('/',$view);
$path=SConfig::system('dir_template');
for($i=0;$i<count($dirs)-1;$i++){
$path.=$dirs[$i];
if(!is_dir($path)){
mkdir($path);
}
$path.=DIRECTORY_SEPARATOR;
}
$content=self::complie($view,file_get_contents($source));
file_put_contents($target,$content);
}
return $target;
}

/**
* 预编译模板
*
* @param string $view 模板名称
* @param string $source 原模板内容
* @return string 编译后结果
*/
static private function complie($view,$source){
//不允许出现PHP代码
if (strpos($source,'<?')!==false){
throw new Exception('Cant\'t user php code in template:'.$view);
}

//替换
$target=preg_replace(
array(
'/<for\b(\(.*\))>/', //匹配 for 循环开始,与PHP语法一致
'/<endfor>/', //匹配 for 循环结束
'/<foreach\b(\(.*\))>/', //匹配 foreach 循环开始,与PHP语法一致
'/<endforeach>/', //匹配 foreach 循环结束
'/<if\b(\(.*\))>/', //匹配 if 开始,与PHP语法一致
'/<elseif\b(\(.*\))>/', //匹配 elseif,与PHP语法一致
'/<else>/', //匹配 else
'/<endif>/', //匹配 if 结束
'/<php>/', //匹配 原生代码开始
'/<\/php>/', //匹配 原生代码结束
'/<include\b(\(.*\))>/', //匹配 子模板包含,语法 <include('子模板',参数数组)>
'/<model\b\(([\w\d]+)\s([\w\d]+)\s(.*)\)>/', //匹配 自我感知,语法 <model(数据 模型名称 方法(参数))>
'/{(.*\))}/', //匹配 显示函数返回值,与PHP语法一致
'/{\$([^}]*)}/', //匹配 显示变量的值,与PHP语法一致
'/<assign\b\((.*)\)>/', //匹配 赋值 <assign($var=exp)>
),
array(
'<?for\1:?>', //替换 For 循环开始
'<?endfor?>', //替换 For 循环结束
'<?foreach\1:?>', //替换 Foreach 循环开始
'<?endforeach?>', //替换 Foreach 循环结束
'<?if\1:?>', //替换 If 开始
'<?elseif\1:?>', //替换 Elseif
'<?else:?>', //替换 Else
'<?endif?>', //替换 If 结束
'<?', //替换 原生代码开始
'?>', //替换 原生代码结束
'<?display\1?>', //替换 子模板包含
'<?$\1=\2::instance()->\3?>', //替换 自我感知
'<?=\1?>', //替换 显示函数返回值的开始
'<?=$\1?>', //替换 显示变量的值
'<?\1?>', //替换 赋值
),$source);

//如果不是调试模式,则去除首尾空格
if(!SDebug::isDebug()){
$target=preg_replace('/^\s*|\s*$/m','',$target);
}
return $target;
}
}

注:大家使用时,要将其中的部分代码进行修改. 将路径,后缀修改为自己项目中的实际路径与后缀,同时调试代码去除.

阅读(163) | 评论(0) | 转发(0) |

0
上一篇:[转]百万级PHP网站架构工具箱

下一篇:配置信息 类

相关热门文章

欢迎skirtburial85在ChinaUnix...

欢迎post7man在ChinaUnix博客...

欢迎kylydhim在ChinaUnix博客...

欢迎mesmerising在ChinaUnix博...

欢迎shenglintech在ChinaUnix...

承接自动化测试培训、外包、实...

Solaris PowerTOP 1.0 发布

For STKMonitor

busybox的httpd使用CGI脚本(Bu...

项目小体会

LNMP 老是会出现502?

suse 运用一个shell获取本机和...

虚拟机 unix 配置ip

hp-un 主机新系统读不到磁盘阵...

mysql出现问题:Starting MySQ...

给主人留下些什么吧!~~

评论热议
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: