zoukankan      html  css  js  c++  java
  • PHP 超级模板引擎

    在进入正题之前先明确几个关键点,有助于帮助我们理解这个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毫秒,那么这完全可以忽略不计.

    因为他使用简单,外加速度非常快,所以就叫他"超级模板引擎"吧!
  • 相关阅读:
    MySQL源代码解读(二)
    MySQL源代码解读(一)
    C语言中如何对串口进行操作
    mysql 运行概图
    Yacc 与 Lex
    外键建索引
    提高SQL查询效率
    MySQL源代码分析:(1)Main函数
    Linux "could not open default font 'fixed'."
    转帖 浅析ARM汇编语言子例程设计方法
  • 原文地址:https://www.cnblogs.com/see7di/p/2239867.html
Copyright © 2011-2022 走看看