算是懂一点正则了,写了一个模板引擎

里面无非就是用正则替换了相对应的语法规则。需要的同学可以拿去看看。

<?php
 private function compile($tpl_file = null) {
  ob_start();
 
  if(empty($tpl_file)) {
   $tpl_file = $this->tpl_file;
  }
 
  //check template file exists
  $tpl_file = $this->config['template_dir'].$tpl_file;
  if(!file_exists($tpl_file) || empty($tpl_file)) {
   die('temlate file no found : '.$tpl_file);
  } else {
   $tpl_str = file_get_contents($tpl_file);
  }
 
  //compile sub template file
  while(preg_match('//ies', $tpl_str, $var)) {
   $sub_tpl_str = $this->compile($var[1]);
   $tpl_str = str_replace($var[0], $sub_tpl_str, $tpl_str);
  }
 
  //{$obj}
  $tpl_str = preg_replace('/\{\s*(\$[a-zA-Z0-9_.]+)\s*\}/is', "", $tpl_str);
  $tpl_str = preg_replace('//is', "", $tpl_str);
  $tpl_str = preg_replace('//ies', "''", $tpl_str);
  $tpl_str = preg_replace('//is', "", $tpl_str);
  $tpl_str = preg_replace('//is', "", $tpl_str);
  $tpl_str = preg_replace('//is', "", $tpl_str);
 
  //
  if(preg_match_all('//ies', $tpl_str, $var)) {
   $loop_head_str = '   $loop_head_str .= '$ROW_INDEX = 0;';
   $loop_head_str .= 'foreach('.$var[1][0].' as '.$var[2][0].'){ $ROW_INDEX++; $ROW_BIT=!($ROW_INDEX%2);
   $tpl_str = preg_replace('//ies', "'$loop_head_str'", $tpl_str);
  }
 
  //
  if(preg_match_all('//ies', $tpl_str, $var)){
   $loop_head_str = '   $loop_head_str .= '$ROW_INDEX = 0;';
   $loop_head_str .= 'foreach('.$var[1][0].' as '.$var[2][0].'=>'.$var[3][0].'){ $ROW_INDEX++; $ROW_BIT=!($ROW_INDEX%2); ?>';
   $tpl_str = preg_replace('//ies', "'$loop_head_str'", $tpl_str);
  }
 
  //$var.property.subproperty
  if(!function_exists('subvar')) {
   function subvar($str) {
    if(!empty($str)) {
     $var_list = explode('.', substr($str, 1));
     foreach($var_list as $var) {
      $var_str .= "['$var']";
     }
     return $var_str;
    }
   }
  }
 
  //$var.property.subproperty
  $tpl_str = preg_replace('/(<\?php+.*?\$[a-zA-Z0-9_]+)([\.a-zA-Z0-9_]*)/ies', "stripslashes('\${1}').subvar('\${2}')", $tpl_str);
  ob_end_flush();
 
  return $tpl_str;
 }
?>

学正则,开发模板引擎

用了一段时间的smarttemplate了,遇到好多不爽的地方
1、不支持变量、常量混写方式;
2、不支持 foreach key 方式循环;
3、不支持 复杂条件判断;
4、不支持 ROW_INDEX, ROW_BIT 加入判断(这个经常用到,TMD 就是不能比较。)

写自己的模板引擎吧,无非就这几个东西:语句识别、编译、静态缓存、插件机制。
附上PHP 的模式符
i :不区分大小写
e:扩展模式,支持 . 表示所有字符,替换函数里面支持函数处理;
s:循环

SmartTemplate 二三事

SmartTemplate 【以下简称ST】 算是一个比较精细的模板引擎了,比起庞大的smarty来,ST显得更加小巧。或者换一句话说,ST 其实就是Smarty的一个儿子罢了,里面的插件、原理基本上都是类似的。 连模块分工都一样(都是分离了一个parse类来处理语法规则和采用命名规则来载入插件。)

使用:

<?php
$st = new SmartTempalte($tpl_file);
$st->assign('var', $var);
echo $st->result();
?>

设置:

<?php
$st->template_dir = 'templates';
$st->temp_dir = 'templates_c';
$st->cache_dir = 'templates_c';
?>

模板语法:
{varname}

特点:支持内嵌PHP代码 ,默认使用 {}分割(字母必须紧跟{}),可以使用css

.style1 { color:red }只需要分离{}和后面字符就可以了(这样不严谨 =__= 容易出错,建议改成其他字符 –>

感觉:用起来没有什么特别的感觉,不过这种机制的模板引擎做到这些功能已经足够应付大部分的网站需求了。 个人觉得除非个人嗜好,要不没有必要呿搬弄庞大的smarty 来。 对于整体项目的应用最好套多一层,这样整体配置起来就简单好多了。 例如

<?php
class Template extends SmartTemplate {
	private static $ins;
	private function __construct(){
		parent:SmartTemplate();
		$this->template_dir = $GLOBALS['setting']['template_dir'];
		$this->temp_dir = $GLOBALS['setting']['template_c'];
		$this->cache_dir = $this->temp_dir;
	}
 
	public static function getInstance(){
		if(!self::$ins){
			self::$ins = new self();
		}
		return self::$ins;
	}
}
?>

使用起来就是这个样子:

<?php
$st = Template::getInstance();
$st->assign('');
$st->result();
?>

不怎么推荐使用模板引擎

人家说使用模板引擎有好处:

1、可以分离结构和业务逻辑;

2、可以方便分工;

3、可以加快页面显示速度;

4、可以缓存。

 

其实个人觉得,上面的问题都不是模板引擎才能解决的问题,只是好多程序员一直没有处理好而已,

1、关于结构和业务逻辑分离,假如程序员自己能够做到所有属于页面表现的代码都放到独立的php文件里面,那么还哪来那么多垃圾代码直接嵌在php 函数里面?

2、用模板引擎也蛮久了,咋不觉得美工他们有那么聪明,难道学会了smarty 语句,还学不会php?

3、4、这两句话是假话来的。 除非直接将php页面转换成为静态html页面,要不模板引擎永远都比不使用慢。好多人在网上看了好多文章都说模板引擎速度多么多么的快,还弄了一堆数据来对比。 自己写模板的时候很少使用模板引擎的静态转换功能。 我自己稍微写了一个小小的静态转换函数足以代替庞大的模板,还要学习多一种语言不觉得无聊么?。

不怎么推荐使用模板引擎 - sobizz - 一葉之秋不怎么推荐使用模板引擎 - sobizz - 一葉之秋