模拟smarty以php为模板的类

来源:互联网 发布:手机淘宝复制链接 编辑:程序博客网 时间:2024/04/30 22:43
<?php
/**
 * 模拟smarty 兼容smarty的以php为模板的class
 *
 * 当前流行把php做为模板,如ZF,Kohana等等.但smarty最大作用不是模板而是分开显示逻辑.
 * 使用在www.tjzl.com时写的,我对smarty不熟悉,删除了些函数,请测试后使用.
 * 如有建议请发到suxiang@126.com,谢谢
 *
 * 重写Smarty的fetch方法读解析后内容.
 * 重写is_cached,是否有正确的缓存
 * 其他函数如append直接拷进来便可
 *
 * @author 苏翔 suxiang@126.com
 */
class SuSmarty
{
    private $resourse='';//模板文件
    private $cachefile='';//缓存文件
    private $_tpl_vars=array();//存储模板中使用的变量

    public $caching=0;//是不是启用缓存
    public $cache_lifetime=3600;//个人觉得600=10分钟合适,对cpu来说同一世纪,但Smarty如此
    public $template_dir='./template';
    public $cache_dir='./cache';

    public function __construct(){
    }

    /**
     * Smarty原始方法
     *
     * @param mixed $tpl_var模板里变量名称或数组(数组含名值对)
     * @access public
     */
    public function assign($tpl_var, $value = null)
    {
        if (is_array($tpl_var)){
            foreach ($tpl_var as $key => $val) {
                if ($key != '') {
                    $this->_tpl_vars[$key] = $val;
                }
            }
        } else {
            if ($tpl_var != '') {
                $this->_tpl_vars[$tpl_var] = $value;
            }
        }
    }

    function clear_all_assign()
    {
        $this->_tpl_vars = array();
    }

    private function getCacheFile( $dirname,$basename )
    {
            return  '/c_'.substr(md5($dirname),0,4).'_'.$basename;
    }

    /**
     * 解析相对或绝对路径的模板文件
     *
     * @param string $res_file 模板里变量名称或数组(数组含名值对)
     * @access private
     */
    private function praseResFile( $res_file )
    {
        //设置模板文件属性
        $a_res_path=explode('/',$res_file);
        $haspath=( count($a_res_path) >1);
        $basename=basename($res_file);

        $dirname=$this->template_dir;

        if(empty($a_res_path[0]) || '.'== $a_res_path[0] || strpos($a_res_path[0],':')){
            //绝对路径
            unset($a_res_path[count($a_res_path)-1]);
            $dirname=join('/',$a_res_path) . '/';
        }else{
            unset($a_res_path[count($a_res_path)-1]);
            $dirname=$this->template_dir.'/'.join('/',$a_res_path) . '/';
        }
        if(! realpath($dirname) ){
            die( "模板路径设置不对 $dirname");
        }elseif(! realpath($this->cache_dir) ){
            die( "缓存路径 $this->cache_dir 不对");
        }
        $this->resourse=$dirname.$basename;
        $this->cachefile=$this->cache_dir . $this->getCacheFile( $dirname,$basename );
    }


    /**
     * 解析模板或从缓存中读取
     *
     *
     * @return string $res_file 缓存文件名称如/home/www/tpl/index.tpl.php 或 index.tpl.php
     */
    public function fetch($res_file)
    {
        $this->praseResFile($res_file);

        //优先读取缓存
        if($this->caching &&  $contents=$this->readCache() ){
            return $contents;
        }

        ob_start();
        extract($this->_tpl_vars , EXTR_OVERWRITE);
        include ( $this->resourse );
        $contents=ob_get_contents();
        ob_end_clean();

        if($this->caching){
            $this->writeCache($contents);
        }

        return $contents;
    }

    public function display($res_file){
        echo $this->fetch($res_file);
    }


    /**
     * 读取缓存
     *
     * @parma bool $is_cached 是否已经检查过正确缓存了
     * @return string
     */
    private function  readCache($is_cached=FALSE)
    {
        if(!$is_cached){
            $is_cached=$this->is_cached();
            if( ! $is_cached){
                return FALSE;
            }
        }
        return file_get_contents($this->cachefile);
    }

    private function writeCache( $content='')
    {
        return file_put_contents($this->cachefile,$content);
    }

    /**
    * 改写smarty函数,是否有缓存且在有效期
    *
    * @return bool
    */
    public function is_cached()
    {
        $lifetime=@filemtime($this->cachefile);
        //echo $lifetime;
        if(!$lifetime){
            return;
        }
        return ( $this->cache_lifetime>  time() - $lifetime  );
    }
}//end class SuSmarty

###例子:###
模板文件如下:
<!-- filename: test.tpl.php -->
<style>
    div{margin:auto auto;width:600px;border:#99FF33 1px solid;}
    div h2{margin:0;border:0;background-color:#99FF33}
    div ul, div li{list-style:none}
</style>
<div>
 <h2>测试 Simple Ugly Smarty 缓存时间<?php echo date( 'H:i:s' , time() )?></h2>
 <ul>
  <?php foreach ($dbToArray as $row):?>
  <li><a href="<?php echo $row['url']?>"><?php echo $row['website']?></li>
  <?php endforeach;?>
 </ul>
</div>

php测试文件如下
//filename example.php

require './SuSmarty.php';
$file_tpl='./tpl/test.tpl.php';
$tpl =new SuSmarty;

$tpl->cache_lifetime=4;//测试使用缓存时间4秒
$tpl->caching=1;
if( $tpl->is_cached() ){
    exit($tpl->fetch($file_tpl)); //读取缓存退出程序
}

$data=array(
    array('url'=>'http://tianya.cn/','website'=>'天涯'),
    array('url'=>'http://php.net/','website'=>'PHP')
    );

$tpl->assign('dbToArray',$data);
$tpl->display($file_tpl);
原创粉丝点击