+ -
当前位置:首页 → 问答吧 → 超级模板引擎

超级模板引擎

时间:2010-10-13

来源:互联网

在进入正题之前先明确几个关键点,有助于帮助我们理解这个PHP模板引擎产生的原因.

什么是PHP模板引擎:
为了能够让表现层和逻辑层分离,方便将来修改前台界面的时候不会改动的逻辑层的逻辑.

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

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

模板引擎类的核心代码如下:
<?php
//author:seven ([email protected])
Class Template{
    var $vars;// 用來保存所有的模板變量
    var $path;// 模板文件存放的路徑,必須/結束

    // 構造函數
    Function Template($path="./tpl/"){
        $this->path = $path;
        $this->vars = array();
    }

    // 重新設置模板文件存放路徑
    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);
    }

    /*
    * 打開,解析,并返回模板文件
    * @參數 (string) 模板文件名
    * @返回 (string)
    */
    Function fetch($file){//array_keys()
        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;                // 返回模板文件執行結果后的內容
    }
}

/**
* 針對Template的擴展類,可以提供自動緩存模板內容的功能
*/
Class ExtTemplate extends Template{
    var $cache_id;
    var $expire;
    var $cached;

    /*
    * 構造函數.
    * @參數 (string) $path 模板文件的路徑
    * @參數 (string) $cache_id 唯一緩存標識
    * @參數 (int) $expire 緩存生存的秒數
    * @返回 (null)
    */
    Function ExtTemplate($path, $cache_id = null, $expire = 900){
        $this->Template($path);
        $this->cache_id = $cache_id ? 'cache/' . md5($cache_id) : $cache_id;
        $this->expire    = $expire;
    }

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

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

    /*
    * 根據cache_id返回被緩存的內容,如果尚未緩存則馬上緩存
    * @參數 (string) $file 模板文件名
    * @返回 (string)
    */
    Function fetchCache($file){
        IF($this->Is_cached()){
            $fp = @Fopen($this->cache_id, 'r');
            $contents = fread($fp, Filesize($this->cache_id));
            Fclose($fp);
            Return $contents;
        }Else{
            $contents = $this->Fetch($file);
            IF($fp = @Fopen($this->cache_id, 'w')){
                Fwrite($fp, $contents);
                Fclose($fp);
            }Else{
                Die('Unable to write cache.');
            }
            Return $contents;
        }
    }
}
?>

模板引擎的实例化:
<?php
Require_once('tpl.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<6000;$i++){
    $arr[$i]=$i;
}

$tpl->setVar($arr);

echo $tpl->fetch('profile.tpl.php');
?>

模板是这样的:
<table cellpadding="3" border="0" cellspacing="1">
    <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>
</table>

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

因为他使用简单,外加速度非常快,所以就叫他"超级模板引擎"吧!
[ 此帖被see7di在2010-10-13 19:35重新编辑 ]

作者: see7di   发布时间: 2010-10-13

你这能算是 模版引擎???

作者: niosan   发布时间: 2010-10-13