`
xcgh
  • 浏览: 75826 次
  • 来自: ...
社区版块
存档分类
最新评论

一个方便易用的小模板处理类

阅读更多
一个方便易用的小模板处理类
在PHP中使用模板技术,一直是一个受欢迎的技术。自从2001年开始,PHP的很多爱好者,在PHP中引用了MVC开发模式后,模板技术就更为火热。

 

网上很多出名的模板引擎,如phplib的template、FastTemplate、easyTPL、BTemplate以及现在受php.net推宠的Smarty模板引擎。

我个人非常喜欢钟爱那些短小精悍的php代码,像Smarty这些动折2000多行的代码实现的模板引擎,一般不是我的钟爱。

前一段时间,看了phpe.net上有一篇文章叫<<超越模板引擎>>感觉那个老外所说确实极其有道理。他这样说:Smarty的目标是"把业务逻辑从表现中分离出来"而不是"PHP代码和HTML代码的分离"。但是Smarty确实也太庞大了,如果我在使用Smarty的话,我会感觉Smarty会不会影响php代码执行效率,首先在解析2000多行的Smarty代码就可能会带来很大延迟。

受<<超越模板引擎>>一文作者影响,我感觉到php本身就是一个嵌入式的脚本语言,如果我们能够使用用简单的php代码写成的模板,而在运行时直接将他include进来那不是更为快捷?比如像如下这个样子的代码:

My name is {myname}.
为什么我们不直接写成
My name is <?=$myname?>.
这样样子呢?

还有模板里常用的列表,其实也是简单的loop

<!-- BEGIN user_list -->
User ID      : {var0}
User Name : {var1}
<!-- END user_list -->

为什么我们不直接写成如下的代码

PHP:
<!---->foreach ( $user_list as $user ) { ?>
User ID : <!---->['id']?>
User Name : <!---->['name']?>
<!---->} ?>


其实早在一年前,我就尝试用这种方法去做一些企业和政府的WebOS,只是当时,还没有意识这样做带来的好处。只是感觉这样的模板我不需要单独的代码去处理他,只是简单的include一下就ok了。而且,我记得当时在做这些用php语言直接写出的模板的时候,非常快捷,以至于到后来,参与开发几个美工都因此对php的程序开发,发生了很大的兴趣,开始学习php的脚本语言。

最近又受<<超越模板引擎>>一文影响,所以决定根据他的思想去实现一个模板处理的类,经过了二三天的每天像榨水果汁一样挤出的几个小时去完成了一个模板类。现在张贴在此,以便能有志同道合朋友能够与我一起讨论。

考虑了现在带会经常使用{name}的这样的标记去做模板,所以我写一个简单的ParseHTM()的方法,去解析这样的文件,将其转换为<?=$name?>这样的php模板。然后将转换后的文件存贮到相应的cache目录中去,然后提供一个ParsePHP()方法去简单的include文件然后在主程序中echo输出。在实现的时候,我为了简化调用方法.使用了一个Parse()方法去呼叫上述两个私有方法.

以下是代码示例:

首先给出目录结构:
 \  根目录
├─cache           存放php模板缓存的文件
├─includes        类库存放目录
│  └─template    模板处理template.php类库文件存放目录
└─templates       模板目录
    ├─imgs           模板文件的图片目录
    │  └─ver.1
    └─tpls           模板文件目录
        └─ver.1

示例一:对于html类型的模板文件的处理.
test.htm.php 模板文件存放在 \templates\tpls\ver.1\目录下
<html>

<head>
    <title>{title}</title>
</head>

<body>
<!-- Trim php code that can't occur in HTML type template file. Now , that will be disable . -->
<?
print_r($_ENV);
?>
<?=$test?>
<? if ( $a == $b ) echo 'a==b'; ?>

<!--IF condition-->
<table border="1" align="center">
    <tr>
        <td>$condition is TRUE</td>
    </tr>
</table>
<!--ENDIF-->

<!--IF a == b-->
<table border="1" align="center">
    <tr>
        <td>$a == $b</td>
    </tr>
</table>
<!--ENDIF-->

<!--IF a != b-->
<table border="1" align="center">
    <tr>
        <td>$a != $b</td>
    </tr>
</table>
<!--ENDIF-->

<table border="1" align="center">
    <tr>
        <td>id</td>
        <td>name</td>
    </tr>

    <!--LIST user_list AS user-->
    <tr>
        <td>{user[id]}</td>
        <td>{user[name]}</td>
    </tr>
    <!--ENDLIST-->
</table>

</body>

</html>

test_htm.php文件对类库调用示例,本文件存放在 \ 目录下
下面是对这样的html类型的模板出理调用的具体过程.

PHP:
<!----> require_once('includes/template/template.php');

$tpl = new Template;
$tpl->SetFile('templates/tpls/ver.1/test.htm.php');

// 对于htm类型模板来说,通过此设置编译后的模板文件
$tpl->SetCacheDir('cache/');

$tpl->SetVar('title','I love jear');
$tpl->SetVar('condition',TRUE);
$tpl->SetVar('a','a');
$tpl->SetVar('b','a');

$user_list = array(
array(
'id' => '1',
'name' => 'Stangly.wrong'
),
array(
'id' => '2',
'name' => 'Jear'
),
);
$tpl->SetVar('user_list',$user_list);

echo $tpl->Parse(TPL_HTM, TRUE);

?>



观察一下目录结构的变化
\
├─cache
│  └─templates
│      └─tpls
│          └─ver.1
├─includes
│  └─template
└─templates
    ├─imgs
    │  └─ver.1
    └─tpls
        └─ver.1

程序会自动在cache目录下,建立与template文件存放的路径相同的目录路径去存放编译后的模板文件。这样个人感觉非常便于查找与排错。

示例二:对于php类型的模板文件的处理,观察一下与htm类型的模板文件有什么不同?是不是所有 {title} 这样的标记都被替换为 <?=$title?>这种形式,以及对于所谓的 block 也被直接替换为 foreach() 方式。

test.php.php 模板文件存放在 \templates\tpls\ver.1\目录下

<html>

<head>
    <title><?=$title?></title>
</head>

<body>

<? if ($condition) { ?>
<table border="1" align="center">
    <tr>
        <td>$condition is TRUE !</td>
    </tr>
</table>
<? } ?>

<? if ($a == $b) { ?>
<table border="1" align="center">
    <tr>
        <td>$a == $b</td>
    </tr>
</table>
<? } ?>

<? if ($a != $b) { ?>
<table border="1" align="center">
    <tr>
        <td>$a != $b</td>
    </tr>
</table>
<? } ?>

<table border="1" align="center">
    <tr>
        <td>id</td>
        <td>name</td>
    </tr>

    <? foreach ( $user_list as $user ) { ?>
    <tr>
        <td><?=$user[id]?></td>
        <td><?=$user[name]?></td>
    </tr>
    <? } ?>
</table>

</body>

</html>

test_htm.php文件对类库调用示例,本文件存放在 \ 目录下
下面是对这样的html类型的模板出理调用的具体过程.

PHP:
<!----> require_once('includes/template/template.php');

$tpl = new Template;
$tpl->SetFile('templates/tpls/ver.1/test.php.php');

// 对于 php 文件来说, 此设置无效
//$tpl->SetCacheDir('cache/');
//

$tpl->SetVar('title','I love jear');
$tpl->SetVar('condition',TRUE);
$tpl->SetVar('a','a');
$tpl->SetVar('b','a');

$users_list = array(
array(
'id' => '1',
'name' => 'Stangly.wrong'
),
array(
'id' => '2',
'name' => 'Jear'
),
);
$tpl->SetVar('user_list',$users_list);

echo $tpl->Parse(TPL_PHP);
?>


以上就是模板类的调用示例,以及模板文件内容的格式。

最后给出template.php文件,他存放于 /includes/template/ 目录下。

PHP:
<!----> // -------------------------------------------------------
// Filename : template.php
// Created : 2004-11-6 13:46
// Author : Stangly.Wrong
// Version : 1.0.0
// Description : Parse template
// Modified : 2004-11-7 15:10
// -------------------------------------------------------

// 定义模板类型
define( 'TPL_HTM', 'htm' );
define( 'TPL_PHP', 'php' );
// 定义默认的缓存目录
define( 'TPL_CACHE_DIR', './cache/');
// 编译后的 TPL_HTM 类型缓存文件名 前缀
define( 'TPL_COMPLIE_FILE_PREFIX','_c_');

Class Template
{
// 模板文件存放的目录
var $_root_dir = NULL;
// 模板文件名
var $_file = NULL;
// 模板文件类型
var $_file_type = TPL_PHP;
// 存贮模板内定义的变量
var $_var = array();

// 编译和缓存文件存放目录
var $_cache_dir = TPL_CACHE_DIR;

// Private function
//
// 参数:
// $f 为PHP类型模板完整路径文件名
//
// 解析php模板文件
//
// 返回解析的结果, 用于直接输出到客户端
//
function &_ParsePHP( $f )
{
if ( !file_exists( $f ) )
{
die('Open file '.$f.' failed !');
}
extract($this->_var);
ob_start();
include($f);
$contents = &ob_get_contents();
ob_end_clean();
return $contents;
}

// Private function
//
// 参数:
// $f 为HTM类型模板完整路径文件名
// $c 确定是否需要重新编译htm模板
//
// 解析htm模板文件
//
// 返回解析的结果, 用于直接输出到客户端
function &_ParseHTM( $f, $c = FALSE )
{
if ( $c )
{
$f = $this->_CompileHTM( $f );
}
else
{
$f = $this->_cache_dir.$this->_root_dir.'/'.TPL_COMPLIE_FILE_PREFIX.$this->_file;
}
return $this->_ParsePHP( $f );
}

// Private function
//
// 参数:
// $f 为HTM类型模板完整路径文件名
//
// 编译htm模板文件
//
// 编译htm模板文件,将存贮到缓存目录中
// 同时返回编译后的文件名
//
function &_CompileHTM( $f )
{
if ( !file_exists( $f ) )
{
die('Open file '.$f.' failed !');
}
ob_start();
$fp = fopen( $f, 'r');
$c = fread($fp, filesize($f));

// 屏蔽php代码
$c = preg_replace('/(\<\?)(.*)(\?\>)/siU', '<!---->', $c);

$c = preg_replace('/<!---->/', '<!---->} ?>', $c);
$c = preg_replace('/<!---->/', '<!---->} ?>', $c);
$p = array(
0 => '/\{([^}]+)\}/',
1 => '/<!---->/',
2 => '/<!---->/',
3 => '/<!---->/',
4 => '/<!---->/',
);
$s = array(
0 => '<!---->\$\1?>',
1 => '<!---->\$\1) { ?>',
2 => '<!---->\$\1 as \$\2 ) { ?>',
3 => '<!---->\$\1 \2 \$\3) { ?>',
4 => '<!---->\$\1 as \$\2 => \$\3 ) { ?>',
);
echo $c = preg_replace($p, $s, $c);
$c = &ob_get_contents();
ob_end_clean();
// 生成需要创建的缓存目录
$d = $this->_cache_dir.$this->_root_dir;
$this->_MakeDirectory( $d );
// 创建编译后的模板文件
$cf = $d.'/'.TPL_COMPLIE_FILE_PREFIX.$this->_file;
if(!@$fp = fopen($cf, 'w'))
{
die('Open file '.$cf.' failed !');
}
flock( $fp, 3 );
fwrite($fp, $c);
fclose($fp);
return $cf;
}

// Private function
//
// 参数
// $d 要创建的目录名
//
// 创建目录
//
function _MakeDirectory( $d )
{
if (is_null($d))
{
return TRUE;
}
$p = explode('/', $d);
foreach ( $p as $k => $v )
{
$prefix .= $v.'/';
if ( is_dir( $prefix ) )
continue;
if (!empty($v) && !@mkdir($prefix, 0777))
die('Cant create cache dir : '.$prefix);
}
return TRUE;
}

/******************************************************************************************/

// 公共成员方法 调用接口
// 初始化成员变量
function Template() {}

// public function
//
// 参数:
// $d 缓存目录路径
//
// 设置缓存和编译文件存放目录
//
function SetCacheDir( $d )
{
$this->_cache_dir = $d;
return TRUE;
}

// Public function
//
// 参数:
// $f 模板文件存放的完整路径名
// $t 模板类型
// TPL_HTM
// TPL_PHP
//
// 设置模板文件存放的目录和文件名以及模板的类型
//
function SetFile( $f = NULL, $t = TPL_HTM )
{
$this->_root_dir = dirname($f);
$this->_file = basename($f);
$this->_file_type = $t;
return TRUE;
}

// Public function
//
// 参数:
// $n 可以为 模板内在{}号内定义的名称
// 或为数组
// $n[]['id'], $n[]['name'], $n[]['sex']
//
// $v 当 $n 为数组时, $v 为空值
//
// 设置模板内定义变量
//
function SetVar( $n, $v = NULL )
{
if ( is_array( $n ) )
{
foreach ( $n as $k => $v )
{
$this->_var[$k] = $v;
}
}
else
{
$this->_var[$n] = $v;
}
return TRUE;
}

// Public function
//
// 参数说明:
// $t 为处理的模板的类型
//
// 对指定的模板进行处理解析 根据 $t 的类型返回不同的结果
//
// $t == TPL_PHP 立即解析返回 html 文件 ( parse -> result )
// $t == TPL_HTM 立即解析返回 html 文件 ( compile -> cache compiled -> parse -> result )
//
// $e == TRUE 时重新编译模板文件 FALSE 使用上一次的编译过的文件
//
function &Parse( $t, $e = FALSE)
{
switch ( $t )
{
case TPL_PHP :
$c = $this->_ParsePHP( $this->_root_dir.'/'.$this->_file );
break;
case TPL_HTM :
$c = $this->_ParseHTM( $this->_root_dir.'/'.$this->_file, $e );
break;
}
return $c;
}
}
?>
分享到:
评论

相关推荐

    仿赶集网站模板.net分类信息管理系统下载

    一个功能强大的分类信息(广告)系统,网软志成分类信息网正式版下载,地方门户系统,分类信息网模板,分类信息网淡红色风格版下载,仿快点8分类信息网门户网站系统源码,供求信息发布网站系统和信息发布网站程序,漂亮的...

    海洋cms影视管理系统v11.3 快速架设海量视频讯息网站+模板众多插件齐全

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    科技模块ppt模板.ppt

    科技幻灯片模板设计 ...本资源提供了一个科技类PPT模板的设计和制作经验,涵盖了PPT模板设计、PSD文件处理、时间管理、团队协作、PPT设计原则、科技风格设计、可视化设计、交互设计等多方面的知识点。

    网软志成分类信息网站系统.net官方商业版

    一个功能强大的分类信息(广告)系统,网软志成分类信息网正式版下载,地方门户系统,分类信息网模板,分类信息网淡红色风格版下载,仿快点8分类信息网门户网站系统源码,供求信息发布网站系统和信息发布网站程序,漂亮的...

    仿58同城赶集网源码

    一个功能强大的分类信息(广告)系统,网软分类信息网正式版下载,分类信息网模板,分类信息网赶集网风格版下载分类信息网站系统源码分类网站模板,供求信息发布网站系统和信息发布网站程序,漂亮的分类信息网站模板....

    生活分类信息发布网站的优秀网站管理系统正式版

    一个功能强大的分类信息(广告)系统,网软志成分类信息网正式版下载,地方门户系统,分类信息网模板,分类信息网淡红色风格版下载,仿快点8分类信息网门户网站系统源码,供求信息发布网站系统和信息发布网站程序,漂亮的...

    海洋cms(海洋视频内容管理系统) v12.5 bulid220618

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    海洋cms(海洋视频内容管理系统) v12.6 bulid220921.zip

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    速成(SuCMS)影视管理系统 v1.0

    速成影视管理系统(SuCms,速成cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需3分钟即可建立一个海量的视频讯息的行业网站。...

    海洋cms(海洋影视管理系统) 视频点播系统源码

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    海洋CMS 影视管理系统

    海洋CMS 影视管理系统,海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的...

    海洋cms(海洋视频内容管理系统) v12.5

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    完整无BUG最新版-海洋影视网完美带采集数据zip

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    discuz x3模板 摄影MEN/图片分享 商业版 摄影人生图片分享社区.rar

    模板介绍: 摄影人生,打造最纯粹的摄影人生图片分享社区 模板有门户频道和论坛页面,框架代码以及大部分模块代码手工编写,从而减少代码冗余问题, ...简单易用性,可以灵活diy,方便网站编辑和运营。

    opencv图像处理素材

    penCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它提供了丰富的图像处理和计算机视觉算法,包括图像处理、特征检测、目标识别、目标跟踪、机器学习等功能。OpenCV 是一个跨平台的库,可以...

    多米(DuomiCms)影视管理系统 视频点播系统 视频网站源码

    简单易用丰富的模板标签,方便网站模板设计制作,让网站更显专业。 DuomiCms是基于PHP+MySql技术开发的影视管理系统,强劲功能、卓越性能、安全健壮。简单易用、制作模板方便。构架稳健,平滑升级。 多米(DuomiCms)...

    seacms海洋cms影视管理系统 v9.1.zip

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    Luocms文章管理系统 v2.0.101201

    : 全站伪静态处理 模板DIV+CSS架构 自定义标题、关健字、描述 自定义栏目模板 自定义内容页模板 上传图片缩略图处理 栏目无限分类 后台添加内容保存远程图片 自定义标题、栏目颜色 标签简便易用

    海洋cms带网络直播

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    速成(SuCMS)影视管理系统 v1.0.rar

    速成影视管理系统(SuCms,速成cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需3分钟即可建立一个海量的视频讯息的行业网站。...

Global site tag (gtag.js) - Google Analytics