php简单 模板技术

<?php

/**php简单 模板技术
 * 作者:牛哄哄
 * QQ:455703030
 * 声明:我正则写的不地道,欢迎高手帮我修改一下
 *      可自由传播、使用,但请保留此信息
 */

class FLEA_View_NHH
{
 //模板存储目录
 public $viewDir = null;
 //缓存存储目录
 public $cacheDir = null;
 //是否过滤缓存中多余空格、Tab、回车
 public $filterCache = true;
 
 //模板中需要显示的数据
 private $data = array();
 
 public function __construct()
 {
  $viewConf = (array)FLEA::getAppInf('viewConfig');
  if (empty($viewConf)) {
   FLEA::loadClass('FLEA_Exception_ExpectedFile');
   __THROW(new FLEA_Exception_ExpectedFile('The config file is not found: '.$viewConf));
  }
  $this->viewDir = $viewConf['viewDir'];
  $this->cacheDir = $viewConf['cacheDir'];
  $this->filterCache = $viewConf['filterCache'];
 }
 
 public function assign($var, $value)
 {
  $this->data[$var] = $value;
 }
 
 public function display($viewName)
 {
  $view = $this->viewDir.'/'.$viewName.'.html';
  $cache = $this->cacheDir.'/'.$viewName.'.php';
  if (!file_exists($view)) {
   FLEA::loadClass('FLEA_Exception_ExpectedFile');
   __THROW(new FLEA_Exception_ExpectedFile('The view file is not found: '.$view));
  }
  if (filemtime($view) > @filemtime($cache)) {
   $this->parseView($view, $cache);
  }
  if (file_exists($cache)) {
   if (!defined('IN_THIS_VIEW')) { define('IN_THIS_VIEW', TRUE); }
   include($cache);
  } else {
   FLEA::loadClass('FLEA_Exception_ExpectedFile');
   __THROW(new FLEA_Exception_ExpectedFile('The cache file has not read in correctly: '.$cache));
  }
 }
 
 private function parseView($view, $cache = null)
 {
  /* 如果模板不存在,则输出错误消息 */
  if (!file_exists($view)) {
   FLEA::loadClass('FLEA_Exception_ExpectedFile');
   __THROW(new FLEA_Exception_ExpectedFile('The view file is not found: '.$view));
  }
  /* 读取模板内容为一个字符串 */
  $view = file_get_contents($view);
  /* 将<!--{ }-->替换为{{ }} */
  $view = str_replace(array('<!--{', '}-->'), array('{{', '}}'), $view);
  /* 清除注释 */
  $view = preg_replace("/\{\{\*(.*?)\*\}\}/", '', $view);
  /* 解析assign方法引入的变量 */
  $view = preg_replace('/\$([A-Za-z0-9_]+)/', '$this->data[\'\\1\']', $view);
  /* 机械模板内部定义变量 */
  $view = preg_replace('/\$\[([A-Za-z0-9_]+)\]/', '$\\1', $view);
  /* 解析{{ $var }}基本变量输出标签 */
  $view = preg_replace('/\{\{\s*\$(.+?)\s*\}\}/', '<? echo $\\1; ?>', $view);
  /* 解析{{ include  }}标签 */
  $view = preg_replace('/\{\{\s*include\s+(.+?)\s*\}\}/', '<? include \\1; ?>', $view);
  /* 解析{{ html  }}标签 */
  $view = preg_replace('/\{\{\s*html\s+(.+?)\s*\}\}/', '<? echo file_get_contents(\\1); ?>', $view);
  /* 解析{{ code  }}标签 */
  $view = preg_replace('/\{\{\s*code\s+(.+?)\s*\}\}/', '<? \\1; ?>', $view);
  /* 解析{{ if  }}标签 */
  $view = preg_replace('/\{\{\s*if\s+(.+?)\s*\}\}/', '<? if (\\1) { ?>', $view);
  /* 解析{{ elseif  }}标签 */
  $view = preg_replace('/\{\{\s*elseif\s+(.+?)\s*\}\}/', '<? } elseif(\\1) { ?>', $view);
  /* 解析{{ while  }}标签 */
  $view = preg_replace('/\{\{\s*while\s+(.+?)\s*\}\}/', '<? while (\\1) { ?>', $view);
  /* 解析{{ foreach  }}标签 */
  $view = preg_replace('/\{\{\s*foreach\s+(.+?)\s*\}\}/', '<? foreach (\\1) { ?>', $view);
  /* 解析{{ for  }}标签 */
  $view = preg_replace('/\{\{\s*for\s+(.+?)\s*\}\}/', '<? for (\\1) { ?>', $view);
  /* 解析{{ else }}标签 */
  $view = preg_replace('/\{\{\s*else\s*\}\}/', '<? } else { ?>', $view);
  /* 解析{{ /while }},{{ /if }},{{ /for }},{{ /foreach }}标签 */
  $view = preg_replace('#\{\{\s*/[a-z]+\s*\}\}#', '<? } ?>', $view);
  /* 递归解析嵌套的子模板 */
  if (preg_match_all('/\{\{\s*view\s+(.+?)\s*\}\}/', $view, $viewsInView)) {
   /* 循环解析此模板中所有子模板,并将解析结果保存到数组$views */
   $viewInViews = array();
   foreach ($viewsInView[1] as $viewInView) {
    $viewInViews[] = $this->parseView(eval('return '.$viewInView.';'));
   }
   /* 将该模板中所有子模板的标签分别替换为其对应的解析结果 */
   $view = str_replace($viewsInView[0], $viewInViews, $view);
  }
  /* 合并相邻标签的解析结果 */
  $view = preg_replace('/\?>\s*<\?/', '', $view);
  /* 如果开启了缓存过滤,则过滤掉其中多余空格、Tab、回车 */
  if ($this->filterCache == true) {
   $view = preg_replace('/\s+/', ' ', $view);
  }
  /* 如果是在解析子模板,则返回解析结果 */
  if ($cache == null) { return $view; }
  /* 加入防止直接访问缓存的代码 */
  $view = '<? if (!defined("IN_THIS_VIEW")) exit("The page is not found!"); ?>'.$view;
  /* 将模板解析结果写入缓存文件 */
  @file_put_contents($cache, $view);
 }
}

/**
 * 一、配置
 * 配置文件请在FLEA的配置文件中修改
 * 格式为:
 * 'viewConfig' => array(
 *   'viewDir' => '',    //模板文件路径
 *   'cacheDir' => '',    //缓存文件路径
 *   'filterCache' => true,   //是否在模板解析完毕后对缓存进行优化
 * );
 *
 * 二、标签
 * 模板文件后缀名为.html
 * 标签同时支持两种<!--{ }-->或{{ }},你可以根据情况自由使用
 * 1、{{* *}}  添加注释,只支持单行,多行的不知道怎么写,郁闷
 * 2、{{ $abc }}  输出一个变量,变量的格式化输出请使用<{code }>标签执行一个函数进行格式化输出
 * 3、{{ $[abc] }}  输出一个模板内部定义的变量,变量名要用中括号括起来
 * 4、{{ include 'abc/bcd.php' }}  包含一个动态文件,这个文件中可使用通过assign方法加入的变量和模板内部定义的变量,但不可以使用本引擎支持的标签
 * 5、{{ html 'abc/bcd.html' }}  包含一个静态文件,此标签仅在PHP5下可用,被包含的文件中不可使用任何变量或标签,此标签可获得几倍于include标签的性能
 * 6、{{ code echo substr($abc,1) }}  执行一段PHP代码,包括赋值,函数等等
 * 7、{{ if $abc==1 }}和{{ elseif $abc==2 }}和{{ /if }}  判断,分支
 * 8、{{ while $abc<1000 }}和{{ /while }}  while循环
 * 9、{{ for $i=0;$i<1000;$i++ }}和{{ /for }}  for循环
 * 10、{{ foreach $abc as $k => $v }}和{{ /foreach }}  foreach循环
 * 11、{{ view 'abc/bcd.html' }}  嵌套另一个模板,支持模板的无限嵌套
 *
 * 注意:
 * 1,include,html,view标签可使用常量来指定路径,这样会更加方便
 * 2,assign引入的变量与模板内部定义的变量采用不同的命名空间,因此可重名
 * 3,对于while,foreach,for循环需要引入的变量,最好采用模板内部定义的变量
 * 4,模板内部定义变量 {{ code $[i]=1 }}
 * 5,所有标签内部不可包含{}大括号,否则无法正确解析
 * 6,所有标签的参数部分必须写为单行,否则无法正确解析
 * 7,在调试时,为方便查看编译结果可关闭缓存优化,发布时,建议开启,可提高性能
 * 8,此模板引擎仅可于FLEA下使用,若需不依赖FLEA的版本,请自行修改
 * 9,标签中的参数使用PHP的语法
 * 10,数组的引用与输出{{ $abc['id'] }}
 * 11,所有标签一律小写
 * 12,标签的参数中不可包含{{或}},否则会解析错误
 */

?>

时间: 2024-08-01 22:26:56

php简单 模板技术的相关文章

PHP中的模板技术

综述: 在多人开发大型PHP项目时,模板技术非常有用,它可以分开美工和程序员的工作,并且方便界面的修改和完善:不仅如此,利用模板技术,我们还可以简单有效地定制或者修改站点.现在我们将要以PHPLIB的模板为例子讲述如何在PHP中应用模板技术. 如何使用PHPLIB模板? 设我们有一个模板, 名为UserTemp,路径为/home/user_dir/user_temp/,它的内容如下: 你订购的是:{Product} 大括号表示Product是一个模板变量. 然后我们编写如下的

关于PHP模板技术的基本概念

概念|模板 如果你正在设计一个交互式网站,你一定会关注两个主要的问题,就是美工和程序.这也是一个网站在建设中抛开其内容之后最关键的要素.通常有两种方式来协调美工和程序之间的关系: 1.先做好美工页面,然后由程序员直接在美工页面的HTML文件中嵌入ASP.JSP.PHP等程序代码. 2.美工和程序同时进行,但这时因为没有页面框架,程序只能做出一些关键代码,双方完成后再进行一次美工页面和程序代码的嵌入合成. 在实际的网站建设过程中,由于人员.进度等环境的限制,大家通常会混合地使用上面两种协调方式.然

深入解析php模板技术原理【一】_php模板

1.模板的由来 在没有模板技术之前,使用PHP开发程序,通常都是php代码和html混编在一起.比如说新闻列表,很可能就是一个newslist.php页面,结构如下: <?  //从数据库中读取出要显示的新闻记录  ?>  <html>  <head>--..  </head>  <body>  <?   While ($news = mysql_fetch_array($result)) {  ?>  <!--输出新闻标题  

简单模板概念

我以前关于模板的理解都是断断续续的,于是准备系统的专研一遍,以为得花去一两天的时间,没想到,不到一个上午,就完成了计划,回头一看,模板也无非就如此而已吗!于是,这篇的题目就叫"简单模板概念". 抛去其他有关书和资料的讲法,我将按照我自己的理解以简单的语言描述模板. (当然,实际上模板有它自己复杂的一面,呵呵,俺不讨论这个) 1.模板的作用<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:o

基于jTemplates、ascx协同工作的酷UI模板技术

在很久很久以前,也就是asp.net ajax刚引起大众关注不久,asp.net ajax团队成员ScottGu发布 了一篇非常实用的文章: 英文:Tip/Trick: Cool UI Templating Technique to use with ASP.NET AJAX for non-UpdatePanel scenarios , 中文:技巧和诀窍:在不用UpdatePanel的情形下可与ASP.NET AJAX 使用的酷UI模板技术 看完之后,非常受用,并给我留下了非常深刻的映像,之后

都只看到了一些简单的技术Demo,如在一个房间里走动

索尼的头戴式VR设备Project Morpheus从发布到今日已经整整3个月了,然而我们都只看到了一些简单的技术Demo,如在一个房间里走动,在水下的一个牢笼中等.今天索尼放出了第一个较为完整的游戏Demo,"街头雪橇". 玩家只需要一个懒人沙发就能够以坐在雪橇上的姿势体验游戏.The Verge的记者在体验了这个Demo后感觉整个游戏非常的流畅,自然.让我们一同在视频中体验一下这个"街头雪橇"吧. >

angularjs可以和服务器端提供的模板技术混用吗

问题描述 angularjs可以和服务器端提供的模板技术混用吗 angularjs可以和服务器端提供的模板技术混用吗,例如在JSP中可以使用angularjs吗? 解决方案 按理说是可以的,虽然我没有用angularjs进行过实战开发...... 解决方案二: 你可以看下微信网页版,他们就是用的angularjs进行开发的

为什么越简单的技术对于开发人员越难

简单 != 容易从Amazon Web服务到 AngularJS之类的web框架,便利性 驱动 着世界上最好的技术.但是,更加快速地.变得有效率的"便利性",经常伴随着一个隐藏的价格标签:为了变得真正有效率,你将不得不花些功夫. 伟大的技术经常貌似简单,新手们直觉上不需要太多努力就可以"学习".当人们认为他们已经掌握了这门技术.而他们真正做的所有工作相当于是一个"hello world"程序的等价物时,问题就出现了.在你归咎于这个工具之前,你往往

jQuery模板技术和数据绑定实现代码_jquery

好消息来了,微软开发出了这样的框架,这是对jQuery的一个扩展,从此以后要在浏览器上动态显示服务器端Web Service返回的数据将变得如同用服务器端控件显示数据一样容易. 这个技术就叫jQuery templates and data linking ,这是微软对jQuery做的一个扩展.这种扩展需要jQuery官方的审核,然后才能被包含在jQuery中.据ScottGu的博客上说,此扩展正在等待审核阶段.但是这些功能却是非常强大而且实用,我就先把它转过来了,先睹为快. 在编写AJAX应用