自行开发的 轻量级 模板引擎
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...
给主人留下些什么吧!~~
评论热议
项目中考虑 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...
给主人留下些什么吧!~~
评论热议
相关文章推荐
- 女儿小学三年级作文
- 技术管理中遇到的一些问题及初步解决想法
- 【整理向】Symfony2 Jobeet Day 3: The Data Model
- [转]软件开发中的11个系统思维定律
- [转]经验之谈:10位顶级PHP大师的开发原则
- [转]微软资深软件工程师:阅读代码真的很难
- [转]百万级访问量网站的技术准备工作
- Python学习心得
- Python 学习笔记
- [转]网站开发人员应该知道的62件事
- [转]软件开发中的11个系统思维定律
- 女儿的作文(小学三年级)
- 08期 张维为 中国模式及其国际意义[转]
- [转]有药也不给你吃
- 招聘 感想
- 小学二年级末 10000以内加减混合运算
- 项目管理是一门艺术
- 技术人员对微软产品的爱与恨
- 创业经验总结
- PHP使用代理访问外部网站的方法