// +---------------------------------------------------------------------- defined('THINK_PATH') or exit(); /** * 系统行为扩展:模板解析 * @category Think * @package Think * @subpackage Behavior * @author liu21st */ class ParseTemplateBehavior extends Behavior { // 行为参数定义(默认值) 可在项目配置中覆盖 protected $options = array( // 布局设置 'TMPL_ENGINE_TYPE' => 'Think', // 默认模板引擎 以下设置仅对使用Think模板引擎有效 'TMPL_CACHFILE_SUFFIX' => '.php', // 默认模板缓存后缀 'TMPL_DENY_FUNC_LIST' => 'echo,exit', // 模板引擎禁用函数 'TMPL_DENY_PHP' => false, // 默认模板引擎是否禁用PHP原生代码 'TMPL_L_DELIM' => '{', // 模板引擎普通标签开始标记 'TMPL_R_DELIM' => '}', // 模板引擎普通标签结束标记 'TMPL_VAR_IDENTIFY' => 'array', // 模板变量识别。留空自动判断,参数为'obj'则表示对象 'TMPL_STRIP_SPACE' => true, // 是否去除模板文件里面的html空格与换行 'TMPL_CACHE_ON' => true, // 是否开启模板编译缓存,设为false则每次都会重新编译 'TMPL_CACHE_PREFIX' => '', // 模板缓存前缀标识,可以动态改变 'TMPL_CACHE_TIME' => 0, // 模板缓存有效期 0 为永久,(以数字为值,单位:秒) 'TMPL_LAYOUT_ITEM' => '{__CONTENT__}', // 布局模板的内容替换标识 'LAYOUT_ON' => false, // 是否启用布局 'LAYOUT_NAME' => 'layout', // 当前布局名称 默认为layout // Think模板引擎标签库相关设定 'TAGLIB_BEGIN' => '<', // 标签库标签开始标记 'TAGLIB_END' => '>', // 标签库标签结束标记 'TAGLIB_LOAD' => true, // 是否使用内置标签库之外的其它标签库,默认自动检测 'TAGLIB_BUILD_IN' => 'cx', // 内置标签库名称(标签使用不必指定标签库名称),以逗号分隔 注意解析顺序 'TAGLIB_PRE_LOAD' => '', // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔 ); // 行为扩展的执行入口必须是run public function run(&$_data){ $engine = strtolower(C('TMPL_ENGINE_TYPE')); $_content = empty($_data['content'])?$_data['file']:$_data['content']; $_data['prefix'] = !empty($_data['prefix'])?$_data['prefix']:C('TMPL_CACHE_PREFIX'); if('think'==$engine){ // 采用Think模板引擎 if((!empty($_data['content']) && $this->checkContentCache($_data['content'],$_data['prefix'])) || $this->checkCache($_data['file'],$_data['prefix'])) { // 缓存有效 // 分解变量并载入模板缓存 extract($_data['var'], EXTR_OVERWRITE); //载入模版缓存文件 include C('CACHE_PATH').$_data['prefix'].md5($_content).C('TMPL_CACHFILE_SUFFIX'); }else{ $tpl = Think::instance('ThinkTemplate'); // 编译并加载模板文件 $tpl->fetch($_content,$_data['var'],$_data['prefix']); } }else{ // 调用第三方模板引擎解析和输出 $class = 'Template'.ucwords($engine); if(class_exists($class)) { $tpl = new $class; $tpl->fetch($_content,$_data['var']); }else { // 类没有定义 throw_exception(L('_NOT_SUPPERT_').': ' . $class); } } } /** * 检查缓存文件是否有效 * 如果无效则需要重新编译 * @access public * @param string $tmplTemplateFile 模板文件名 * @return boolean */ protected function checkCache($tmplTemplateFile,$prefix='') { if (!C('TMPL_CACHE_ON')) // 优先对配置设定检测 return false; $tmplCacheFile = C('CACHE_PATH').$prefix.md5($tmplTemplateFile).C('TMPL_CACHFILE_SUFFIX'); if(!is_file($tmplCacheFile)){ return false; }elseif (filemtime($tmplTemplateFile) > filemtime($tmplCacheFile)) { // 模板文件如果有更新则缓存需要更新 return false; }elseif (C('TMPL_CACHE_TIME') != 0 && time() > filemtime($tmplCacheFile)+C('TMPL_CACHE_TIME')) { // 缓存是否在有效期 return false; } // 开启布局模板 if(C('LAYOUT_ON')) { $layoutFile = THEME_PATH.C('LAYOUT_NAME').C('TMPL_TEMPLATE_SUFFIX'); if(filemtime($layoutFile) > filemtime($tmplCacheFile)) { return false; } } // 缓存有效 return true; } /** * 检查缓存内容是否有效 * 如果无效则需要重新编译 * @access public * @param string $tmplContent 模板内容 * @return boolean */ protected function checkContentCache($tmplContent,$prefix='') { if(is_file(C('CACHE_PATH').$prefix.md5($tmplContent).C('TMPL_CACHFILE_SUFFIX'))){ return true; }else{ return false; } } }