设为首页 收藏本站
查看: 1382|回复: 0

[经验分享] PHP 超级模板引擎

[复制链接]

尚未签到

发表于 2015-8-23 11:26:40 | 显示全部楼层 |阅读模式
在进入正题之前先明确几个关键点,有助于帮助我们理解这个PHP模板引擎产生的原因.
  //如果要轉載本文請注明出處,免的出現版權紛爭,我不喜歡看到那種轉載了我的作品卻不注明出處的人 Seven{See7di#Gmail.com}
什么是PHP模板引擎:
为了能够让表现层和逻辑层分离,方便将来修改前台界面的时候不会改动的逻辑层的逻辑.

一个好的模板引擎需要具备哪些素质:
能够很好的把表现层和逻辑层分离
不可以影响前台的访问浏览速度
使用简单

参数对比:
现在市面上PHP的模板引擎不计其数,基本上每个模板引擎都能实现逻辑层和表现层的分离,那么接下来我们需要考虑的就是方便使用和解析速度的问题了.
首先我们看速度方面,目前市面上速度最快的模板引擎应该就是smarty(其他那些模板引擎的速度不敢恭维,抛开不谈),但是他臃肿,他有一套属于他自己的模板语言,对于每一个使用者来说都要学会他的模板语言才能够正常使用,这一点来讲它在使用简单方面就没有任何的优势,因此针对以上问题我制作了自己的模板引擎,即您即将看到的超级模板引擎.

模板引擎类的核心代码如下:
<?php
/**
* Copyright (c) 2010-10-13 F. seven (See7di@Gmail.Com)
*/

Class Template{
var $vars;        // 用來保存所有的模板變量
var $path;        // 模板文件存放的路徑,必須/結束
var $debug;        // 是否开启调试模式
var $expire;
var $cached;
var $cacheid;

/* 構造函數
* @參數 (string) $path 模板文件的路徑
* @參數 (int) $expire 緩存的有效期(秒)
* @返回 (null)
*/
Function Template($expire=900,$debug=False,$path="./tpl/"){
$this->path = $path;
$this->vars = array();
$this->debug = $debug;
$this->expire = $expire;

//根据逻辑层文件的md5值计算cacheid,可防止产生垃圾缓存
$this->cacheid = 'cache/'.Md5_file(Realpath("./").Basename($_SERVER["PHP_SELF"]));
}

// 重新設置模板文件存放路徑
Function setPath($path){
$this->path = $path;
}

/*
* 設置模板內使用的變量
* @參數 (string) $name 需要設置的變量名
* @參數 (mixed) $value 該變量的值
* @返回 (null)
*/
Function set($name, $value){
$this->vars[$name] = $value;
}

/*
* 将模板变量合并或重写存放到一个数组内
* @參數 (array) $vars 待操作數組名
* @參數 (bool) $clear 是否允許重寫已存在的變量
* @返回 (null)
*/
Function setVar($vars, $clear = False){
IF($clear){
$this->vars = $vars;
}Else{
IF(Is_array($vars)){
$this->vars = Array_merge($this->vars, $vars);
$this->vars = $this->FormatKey($this->vars);
}
}
}

/*
* 将数字索引的数组键值修改成符合变量标准的键值
* @例子 Array("a"=>"a","b",3=>"c")转换之后是Array("a"=>"aa","_0"=>"b","_3"=>"c")
* @參數 (array) 待格式化的数组
* @返回 (array)
*/
Function FormatKey($arr){
$_keys=Array_keys($arr);
Foreach($_keys as $key=>$value){
IF(Is_numeric($value)){
$_keys[$key]="_".$value;
}
}
Return Array_combine($_keys,$arr);
}

/*
* 根據cacheid判斷當前的緩存是否有效
* @返回 (bool)
*/
Function Is_cached(){
IF($this->cached){Return True;}
IF(!$this->cacheid){Return False;}
IF(!File_exists($this->cacheid)){Return False;}
IF(!($mtime = Filemtime($this->cacheid))){Return False;}

// 緩存是否已過期?
IF(($mtime + $this->expire) < time()){
@Unlink($this->cacheid);
Return False;
}Else{
$this->cached = True;
Return True;
}
}

/*
* 打開,解析,并返回模板文件
* @參數 (string) 模板文件名
* @返回 (string)
*/
Function Fetch($file){
IF(!File_Exists($this->path . $file)){Return False;}
Extract($this->vars);            // 提取變量到當前命名空間
OB_start();                        // 開始輸出緩沖
OB_clean();                        // 清理原有內容
Include($this->path . $file);    // 調用模板文件
$contents = ob_get_contents();    // 取得緩存區內容
ob_end_clean();                    // 結束緩沖區
Return $contents;                // 返回模板文件執行結果后的內容
}

/*
* 根據cacheid返回被緩存的內容,如果尚未緩存則馬上緩存
* @參數 (string) $file 模板文件名
* @返回 (string)
*/
Function FetchCache($file){
IF($this->Is_cached()){
IF($this->debug){Echo "<br>{直接读缓存}<br>";}
$fp = @Fopen($this->cacheid, 'r');
$contents = fread($fp, Filesize($this->cacheid));
Fclose($fp);
Return $contents;
}Else{
IF($this->debug){Echo "<br>{写入并返回缓存}<br>";}
$contents = $this->Fetch($file);
IF($fp = @Fopen($this->cacheid, 'w')){
Fwrite($fp, $contents);
Fclose($fp);
}Else{
Die('Unable to write cache.');
}
Return $contents;
}
}
}
?>

模板引擎的实例化:
<?php
//注意:一旦手工修改过实例化文件后最好是删掉所有缓存文件,让其重新缓存一次
Require_once('Template.php');

$tpl = &New Template();
$tpl->set('title', 'User Profile');
$arr = Array();

$arr = Array(
"a"=>1,
"b"=>"b",
"c"=>array(12,23)
);
$arr["d"]=array("第一个","第二个");

For($i=0;$i<10;$i++){
$arr[$i]="值{$i}";
}

$tpl->setVar($arr);
//echo $tpl->fetch('tpl1.php');
Echo $tpl->fetchCache('tpl1.php');
?>

模板是这样的:
相关的模板是这样的:<br>
<table cellpadding="3" border="0" cellspacing="1">
<tr>
<td><a href='1.php' title=''>1.php</a></td>
<td><a href='index.php' title=''>index.php</a></td>
</tr>
<tr>
<td>键值A:</td>
<td><?=$a;?></td>
</tr>
<tr>
<td>键值B:</td>
<td><?=$b;?></td>
</tr>
<tr>
<td>键值C:</td>
<td><?PHP
For($i=0;$i<count($c);$i++){
Echo $c[$i]."<br>";
}
?></td>
</tr>
<tr>
<td>键值D:</td>
<td><?PHP
For($i=0;$i<count($d);$i++){
Echo $d[$i]."<br>";
}
?></td>
</tr>
<tr>
<td>后期扩展的</td>
<td><?PHP
For($i=0;$i<10;$i++){
Echo ${"_".$i}."<br>";
}
?></td>
</tr>
</table>

我为什么要这样做呢?
因为我认为PHP的循环比任何模板引擎里边的模板语言循环更简单且更容易理解,这一点对于制作前台表现的美工来说并不难学习,而对于那些原来就懂得PHP程序编写的程序员来说简直就是手到擒来,根本就不需要再学习一门新的模板语言.既然如此何乐而不为呢?
另外这样的模板引擎速度比市面上速度最快的模板引擎smarty速度更是快了很多倍,以循环10000次做测试,仅仅比直接使用PHP的echo输出慢接近8毫秒,既然是10000次慢8毫秒,那么这完全可以忽略不计.

因为他使用简单,外加速度非常快,所以就叫他"超级模板引擎"吧!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-102924-1-1.html 上篇帖子: php中json_encode中文编码问题 下篇帖子: PHP学习笔记(10) phpcms模块开发,让swfupload为我所用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表