+ -
当前位置:首页 → 问答吧 → 浅谈模板引擎类的工作机制

浅谈模板引擎类的工作机制

时间:2008-12-23

来源:互联网

这是论坛上千些日子比较火的一个模板类,据说很好很强大的,我们来谈谈她
以下我的评论用红色的字标出

<?php
/**
*  PHP Template Class
*
* @author [email protected]
* @version 1.0
* @copyright GPL 2007
*/
class Template {
/**
    * @desc template file dir
    */
var $tpl_dir   = 'templates/';
var $tpl_file  ;
/**
    * @desc template compiled dir
    */
var $compile_dir    = 'templates_c/';
var $cache_dir      = 'cache/';
var $cache_lifetime = 1800;
/*
这是初始化类的函数,作者这就不对了,没有很好的兼容php4和php5
function __construct($tpl_file) {
    $this->Template($tpl_file);
  }
加上这个貌似更好一些
*/
function Template($tpl_file){
  $this->tpl_file = $tpl_file;
}
/**
    * @desc run compiled template file
    * @param string $tpl_file template file name
    */
/*
检查是否重新生成编译模板用的,说白了就是检测下原始模板生成时间,然后再判断是否重新写入一次
*/
function compiledFile(){
  //where to save compiled file
  $compiled_tpl_file= $this->compile_dir. $this->tpl_file .".php";
  //compiled file wherther older than templdate file
  if ( @filemtime($compiled_tpl_file) < filemtime($this->tpl_dir. $this->tpl_file) ){//本函数的核心
   $this->compiled_tpl_file = $compiled_tpl_file;
   $this->compile();
  }
  return $compiled_tpl_file;
}
/**
     * @desc compile template file
     */
/*
重头戏来了~所谓的模板核心也就是这里了
大家不要把模板类想的多神秘,看看下面的代码,不就是几个替换函数么
把模板里的约定好的参数替换成php可识别的代码即可
我最想不通的就是为什么要让观众们重新去学习一个新的语法,学习php已经不容易了,还要去学习所谓的模板语言,现在模板作者真是不付责任
就简单的if else来说吧,非要搞的那么复杂,无非就是要抛掉{}的问题嘛,你可以使用原生态的if(...) :               endif;  不就很容易避开了那个{}的问题么,
也更为简单了,嗨。。 for函数也是支持这种用法的,所以可以省却很多这样的编译时间的
最后:我最鄙视的就是这个函数了
*/
function compile(){
  if(!($str=file_get_contents($this->tpl_dir . $this->tpl_file))){
   exit('read tpl file error');
  }
  //check if has sub template
  if( strpos($str,'include ')!==false ){
   preg_match_all('/\{\s*include file=["\']?([a-zA-Z0-9_.]+)[\'"]?\s*\}/i', $str, $tvar);
   foreach($tvar[1] as $subfile) {
    if(!($subst=file_get_contents($this->tpl_dir . $subfile))) {
     $subst = 'TemplateParser complier Error: Subtemplate not found: \''.$subfile.'\'';
    }
    $str = preg_replace("/\{\s*include file=[\"']?${subfile}[\"']?\s*\}/i", $subst, $str);
   }
  }
  $str = preg_replace( array (
  '/<!--\s*if(\[|\()(.+?)(\]|\))\s*-->/is',
  '/<!--\s*elseif(\[|\()(.+?)(\]|\))\s*-->/is',
  '/<!--\s*else\s*-->/is',
  '/<!--\s*end\s*-->/is',
  '/<!--\s*([a-zA-Z0-9_\$\[\]\'\"]{2,60})\s*(AS|as)\s*(.+?)\s*-->/',
  '/(\{\s*|<!--\s*)row\:(.+?)(\s*\}|\s*-->)/eis', //换行
  '/\{\$([a-zA-Z0-9_\'\"\[\]\$]+)\}/',
  '/\{\%([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/s',
  '/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/',
  ),
  array(
  '<?php if([url=file://\\2){?]\\2){?>'[/url],
  '<?php }elseif([url=file://\\2){?]\\2){?>'[/url],
  '<?php }else{?>',
  '<?php }?>',
  '<?\$_i=0; foreach((array)\\1 AS [url=file://\\3){\$_i++;?]\\3){\$_i++;?>'[/url],
  '$this->col("[url=file://\\2")]\\2")'[/url],
  '<?php echo \$\\1;?>',
  "<?php echo \$lang['\\1'];?>",
  '<?php echo [url=file://\\1;?]\\1;?>'[/url],
  ),
  $str);
  $res = $this->saveFile($this->compiled_tpl_file,$str);
}
/**
* desc 换行函数
* col(每行单元格数,换行内容);
* col("5,</tr><tr>");
*/
function col( $input='' ) {
  $input = str_replace(' ','',$input);
  if($input!=''){
   list($num,$alter)  = explode(',',$input);
   if($alter){
    $a  = explode(":",$alter);
    $res = "if(\$_i%$num===0){\$row_count++;echo(\$row_count%2===0)?'</tr><tr bgcolor=\"$a[0]\">':'</tr><tr bgcolor=\"$a[1]\">';}";
   }else{
    $res = "if(\$_i%$num===0){echo '</tr><tr>';}";
   }
   return '<?php '.$res.'?>';
  }
}
/**
     * @desc save string to file   
     * @return boolean
     */
function saveFile($filename,$str) {
  if ($fp = fopen($filename, "w")) {
   fputs($fp, $str);
   fclose($fp);
  }
}
/**
        * Start Ouput Content Buffering
        * @desc Output Cache
        */
/*
上面的两个函数我没有什么好说的,简单的封装操作

我们来看看这个缓存函数吧,核心就是 ob_start 的使用,注意里面的回调函数,呵呵,很有意思的一个应用
*/
function useCache ( $cache_file = null ){
  if (empty($_POST)){
   $this->cache_filename  = $cache_file
   ? $cache_file : $this->cache_dir . md5($_SERVER['REQUEST_URI']) . '.htm';
   if ((time() - @filemtime($this->cache_filename)) < $this->cache_lifetime) {
    readfile($this->cache_filename);
    exit;
   }
   ob_start( array( &$this, '_cacheCallback' ) );
  }
}
function _cacheCallback ( $output ) {
  $this->saveFile($this->cache_filename,$output);
  return $output;
}
}
?>


好了,我就先说这么多吧,欢迎大家扔鲜花,鸡蛋也照收,哈哈

作者: loveaf   发布时间: 2008-12-23

不错 支持了

作者: abcnic   发布时间: 2008-12-23

<?php foreach($x as $xx):?> <?php endforeach;?>   感觉不用那些模板清晰多了,性能比他们还好

作者: yzxh24   发布时间: 2008-12-23

hen hao

作者: xuguoqin22   发布时间: 2008-12-24

http://www.fenanr.com/sindex.html  phpnew 4.0

作者: 冯.于安   发布时间: 2008-12-24

楼上的这个不错

作者: niceup   发布时间: 2008-12-24

好好好好

作者: 自由活动   发布时间: 2009-03-26

自己写的模板引擎
http://bbs.phpchina.com/redirect ... o=lastpost#lastpost
大家给点意见

作者: hxhui08   发布时间: 2009-03-28