您的位置:首页 > 编程语言 > PHP开发

PhpView:一个以PHP语言为模板语言的模板类

2017-06-30 14:15 162 查看
PhpView:一个以PHP语言为模板语言的模板类  
  
  
  
作者:谢声涛 shishengsoft@gmail.com  
  
  
  
Smarty用来实现代码与界面的分离,确实是一种不错的选择。但是Smarty有自创的一套语法,  
  
使用起来感觉很麻烦,于是想到用PHP语言实现一个精简的模板类,名字就叫PhpView。  
  
其实,最简单的模板机制就是在PHP脚本文件中include一个模板文件。但是这样缺点比较多。  
  
  
  
一、使用示例  
  
  
  
<?php  
  
  
  
$t = new PhpView();  
  
  
  
$t->templateDir  = './template';  
  
$t->cacheDir     = './cache';  
  
$t->serializeDir = './serialize';  
  
  
  
$t->assign('title', $title);  
  
$t->assign('hello', $hello);  
  
  
  
$t->display("example.html");  
  
  
  
?>  
  
  
  
如上所示,和Smarty的接口很相似,好像现在一些PHP模板类都是大同小异的。  
  
  
  
  
  
二、实现代码  
  
  
  
文件名:PhpView.class.php  
  
  
  
<?php  
  
/******************************************************************************* 
 
 * 简介: 
 
 * 1、模板语言使用PHP语言,而其它模板类使用自定义的专用语言,需要进行正则替换。 
 
 * 2、支持缓存机制,模板数据变化,就刷新缓存文件。 
 
 * 3、可以设定缓存时间,缓存过期,就刷新缓存文件。 
 
 * 4、支持配置文件方式初始化设定目录,也可以后期更改目录,更加灵活(也许是多余)。 
 
********************************************************************************/  
  
/** 
 
 * PHP视图模板类 
 
 * @class    PhpView 
 
 * @author   xie sheng tao <xie.s.t@163.com> 
 
 */  
  
class PhpView  
  
{  
  
    /** 
 
     * 是否使用缓存机制进行工作 
 
     * @var  boolean  $cacheEnable   true-启用缓存机制;false-关闭缓存机制 
 
     */  
  
    public $cacheEnable = true;  
  
  
  
    /** 
 
     * 缓存时间 
 
     * 超过缓存时间则自动更新缓存。 
 
     * @var  integer     $cacheExpire  0-永远不过期;> 0 判断。< 0 ?? 或者 = 0 始终过期;> 0 判断;< 0 永远不过期 
 
     */  
  
    public $cacheExpire = 0;  
  
      
  
    /** 
 
     * 模板文件的存贮目录 
 
     * @var  string  $templateDir 
 
     */  
  
    public $templateDir = '';  
  
  
  
    /** 
 
     * 缓存文件的存贮目录 
 
     * @var string   $cacheDir 
 
     */  
  
    public $cacheDir = '';  
  
  
  
    /** 
 
     * 序列化文件的存贮目录 
 
     * @var  string  $serializeDir 
 
     */  
  
    public $serializeDir = '';  
  
  
  
    /** 
 
     * 保存模板文件中使用的变量的名、值列表 
 
     * @var  array   $m_templateVarList 
 
     */  
  
    private $m_templateVarList = array();  
  
  
  
    /** 
 
     * 记住系统目录是否已经检查过并且符合要求。避免以全局方式使用时重复检查。 
 
     * @var  boolean     $m_sysDirReady   
 
     */  
  
    private $m_sysDirReady = false;  
  
  
  
    /** 
 
     * 当前操作使用的模板文件 
 
     * @var  string  $m_templateFile 
 
     */  
  
    private $m_templateFile = '';  
  
  
  
    /** 
 
     * 类的构造函数 
 
     */  
  
    public function __construct()  
  
    {  
  
        $this->readConfig();  
  
    }  
  
      
  
    /** 
 
     * 读取PhpView类的配置信息 
 
     */  
  
    public function readConfig()  
  
    {  
  
        if(file_exists("config.php"))  
  
        {  
  
            include_once("config.php");  
  
        }  
  
        if(isset($g_cacheEnable))  
  
        {  
  
            $this->cacheEnable = $g_cacheEnable;  
  
        }  
  
        if(isset($g_templateDir))  
  
        {  
  
            $this->templateDir =$g_templateDir;  
  
        }  
  
        if(isset($g_cacheDir))  
  
        {  
  
            $this->cacheDir = $g_cacheDir;  
  
        }  
  
        if(isset($g_serializeDir))  
  
        {  
  
            $this->serializeDir = $g_serializeDir;  
  
        }  
  
        if(isset($g_sysDirReady))  
  
        {  
  
            $this->m_sysDirReady = $g_sysDirReady;  
  
        }  
  
    }  
  
  
  
    /** 
 
     * 检测所需目录是否存在。如果不存在,则报错并退出。 
 
     * 所需目录为:模板文件目录、缓存文件目录、序列化文件目录 
 
     */  
  
    public function checkSysDir()  
  
    {  
  
        if($this->templateDir == '')  
  
        {  
  
            die("模板文件目录未设置。");  
  
        }  
  
          
  
        if(!is_readable($this->templateDir))  
  
        {  
  
            die("模板文件目录不可读。");  
  
        }  
  
  
  
        if($this->cacheDir == '')  
  
        {  
  
            die("缓存文件目录未设置。");  
  
        }  
  
          
  
        if(!(is_readable($this->cacheDir) && is_writable($this->cacheDir)))  
  
        {  
  
            die("缓存文件目录不可读写。");  
  
        }  
  
          
  
        if($this->serializeDir == '')  
  
        {  
  
            die("序列化文件目录未设置。");  
  
        }  
  
          
  
        if(!(is_readable($this->serializeDir) && is_writable($this->serializeDir)))  
  
        {  
  
            die("序列化文件目录不可读写。");  
  
        }  
  
          
  
        $this->m_sysDirReady = true;  
  
        return;  
  
    }  
  
  
  
    /** 
 
     * 指派模板文件中使用的变量 
 
     * @param   string  $varName   在模板中使用的变量名 
 
     * @param   any     &$varValue  PHP中支持的数据类型 
 
     * or 
 
     * @param   array   $varName    使用数组来传递名值列表,即变量名作为关联索引,变量值为元素值。 
 
     */  
  
    public function assign($varName, $varValue = null)  
  
    {  
  
        if(func_num_args() == 1)  
  
        {  
  
            $varList = func_get_arg(0);  
  
            if(gettype($varList) == 'array')  
  
            {  
  
                foreach($varList as $name=>$value)  
  
                {  
  
                    $this->m_templateVarList[$name] = $value;  
  
                }  
  
            }  
  
        }  
  
        else if(gettype($varName) == 'string')  
  
        {  
  
            $this->m_templateVarList[$varName] = $varValue;  
  
        }  
  
        return;  
  
    }  
  
  
  
    /** 
 
     * 调用模板文件,生成模板中的变量,输出到浏览器 
 
     * @param   string  $file  模板文件名 
 
     */  
  
    public function display($file)  
  
    {  
  
        if(!$this->m_sysDirReady)  
  
        {  
  
            $this->checkSysDir();   
  
        }  
  
          
  
        $this->m_templateFile = $file;  
  
          
  
        if($this->cacheEnable)  
  
        {  
  
            $this->cacheOutput();  
  
        }  
  
        else  
  
        {  
  
            $this->directOutput();  
  
        }  
  
        return;  
  
    }  
  
  
  
    /** 
 
     * 使用缓存机制处理模板 
 
     * 实现原理: 
 
     * 1、取得客户端请求的链接url。缓存文件和序列化文件的文件名使用此url命名。 
 
     * 2、将存贮当前模板变量的数组序列化为一个字符串。 
 
     * 3、读取模板文件对应的序列化文件,得到前一个模板变量数组的序列化字符串。 
 
     * 4、判断前后两次序列化字符串是否相等。如果相等,则直接把缓存文件的内容输出到浏览器。 
 
     *    否则,重新生成序列化文件和缓存文件,然后把模板处理结果输出到浏览器。 
 
     */  
  
    private function cacheOutput()  
  
    {  
  
        $html = '';  
  
        $cache_filename = @urlencode(basename(SERVER['REQUEST_URI']));  
  
        $cur_serialize = @serialize($this->m_templateVarList);  
  
        $pre_serialize = $this->readSerialize($cache_filename);  
  
  
  
        if($cur_serialize === $pre_serialize)  
  
        {  
  
            if(!$this->isCacheFileTimeout($cache_filename)){  
  
                if($html = $this->readCacheFile($cache_filename))  
  
                {  
  
                    echo '使用缓存文件.';  
  
                    echo $html;  
  
                    return;  
  
                }  
  
            }  
  
            echo '缓存文件过期.';  
  
        }  
  
          
  
        echo '刷新缓存文件.';  
  
        $this->saveSerialize($cache_filename, $cur_serialize);  
  
        /*foreach($this->m_templateVarList as $name => $value) 
 
        { 
 
            eval("/$name = /$value;"); // 通过 eval 函数生成模板文件中使用的变量 
 
        }*/  
  
        extract($this->m_templateVarList);  
  
  
  
        ob_start();  
  
        @include($this->templateDir . '/' . $this->m_templateFile);  
  
        //sleep(5);  
  
        $html = ob_get_contents();  
  
        ob_clean();  
  
        $this->writeCacheFile($cache_filename, $html);  
  
        echo $html;  
  
        return;  
  
    }  
  
  
  
    /** 
 
     * 直接将模板处理结果输出到浏览器,不使用缓存机制 
 
     */  
  
    private function directOutput()  
  
    {  
  
        foreach($this->m_templateVarList as $name => $value)  
  
        {  
  
            eval("/$name = /$value;"); // 通过 eval 函数生成模板文件中使用的变量  
  
        }  
  
        ob_start();  
  
        @include($this->templateDir . '/' . $this->m_templateFile);  
  
        ob_flush();  
  
        return;  
  
    }  
  
  
  
    /** 
 
     * 将模板处理结果写入缓存文件 
 
     * @param    string  $file       缓存文件路径 
 
     * @param    string  $content    缓存内容 
 
     * @return   null 
 
     */  
  
    private function writeCacheFile($file, $content)  
  
    {  
  
        $filename = $this->cacheDir . '/' . $file;  
  
        @file_put_contents($filename, $content);  
  
        return;  
  
    }  
  
  
  
    /** 
 
     * 读取缓存文件 
 
     * @param    string  $file   缓存文件路径 
 
     * @return   string          缓存文件的内容 
 
     */  
  
    private function readCacheFile($file)  
  
    {  
  
        $filename = $this->cacheDir . '/' . $file;  
  
        $html = @file_get_contents($filename);  
  
        return $html;  
  
    }  
  
          
  
    /**  
 
     * 保存序列化字符串到文本文件中 
 
     * @param    string  $file       序列化文件路径 
 
     * @param    string  $content    序列化数据的字符串 
 
     * @return   null 
 
     */  
  
    private function saveSerialize($file, $content)  
  
    {  
  
        $filename = $this->serializeDir . '/' . $file;  
  
        @file_put_contents($filename, $content);  
  
        return;  
  
    }  
  
  
  
    /** 
 
     * 读取文本文件中存贮的序列化字符串 
 
     * @param    string  $file       序列化文件路径 
 
     * @return   string              序列化数据的字符串 
 
     */  
  
    private function readSerialize($file)  
  
    {  
  
        $filename = $this->serializeDir . '/' . $file;  
  
        $content = @file_get_contents($filename);  
  
        return $content;  
  
    }  
  
  
  
    /** 
 
     * 判断缓存文件是否过期 
 
     * @param    string      $file   缓存文件 
 
     * @return   boolean 
 
     */  
  
    private function isCacheFileTimeout($file)  
  
    {  
  
        if($this->cacheExpire == 0)//缓存时间为0,表示永远不过期  
  
        {  
  
            return false;  
  
        }  
  
  
  
        $cacheFile = $this->cacheDir . '/' . $file;  
  
        if(file_exists($cacheFile))  
  
        {  
  
            $modifyTime = filemtime($cacheFile);  
  
            $currentTime = time();  
  
            if(($currentTime - $modifyTime) > $this->cacheExpire){  
  
                return true;  
  
            }  
  
            return false;  
  
        }  
  
        return true;  
  
    }  
  
  
  
} // end class  
  
  
  
?> 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: