ThinkPHP在设计时没有考虑过把__XXX__这种模板常量用在一些PHP操作上,比如模板继承、Include标签统统不能用模板常量,比如下面这样ThinkPHP是不解析的,直接过滤掉。
<include file="__PUBLIC__/nav.html" />
其原因有2
比如引用js文件你可以这样
127.0.0.1/nut_shop/Public/jQuery.js
而引用PHP文件则需要
./Public/nav.html
路径种类是不同的,就算ThinkPHP解析,最后的执行结果也是错的,更何况ThinkPHP不解析。
所以,如果你非要用,可以定义参考手册中“模板替换”章节定义一个模板常量
TMPL_PARSE_STRING' =>array( __FILE_PUBLIC__' => './Public', )
不过尽管你定义了,还是会被无情的过滤掉,参考下面。
简单说下ThinkPHP的模板渲染流程,参考文件:
.\ThinkPHP\Library\Think\Template.class.php
流程如下:
所以我们需要修改代码让流程变成这样
这样就好了。
改动代码如下,参考原ThinkPHP代码,带PeA标示的为新增的代码:
protected function compiler($tmplContent) { //PeA:模版编译过滤标签,替换各种__XXX__常量 //PeA:这里在开始解析一遍,解析完布局和继承解析一遍,末尾再解析一遍,可以确保include等特殊标签页支持__XXX__常量 Hook::listen('template_filter',$tmplContent); //模板解析 $tmplContent = $this->parse($tmplContent); // 还原被替换的Literal标签 $tmplContent = preg_replace_callback('/<!--###literal(\d+)###-->/is', array($this, 'restoreLiteral'), $tmplContent); // 添加安全代码 $tmplContent = '<?php if (!defined(\'THINK_PATH\')) exit();?>'.$tmplContent; // 优化生成的php代码 $tmplContent = str_replace('?><?php','',$tmplContent); // 模版编译过滤标签,替换各种__XXX__常量 Hook::listen('template_filter',$tmplContent); return strip_whitespace($tmplContent); } protected function parseInclude($content, $extend = true) { // 解析继承 if($extend) $content = $this->parseExtend($content); // 解析布局 $content = $this->parseLayout($content); //PeA:模版编译过滤标签,替换各种__XXX__常量 Hook::listen('template_filter',$content); // 读取模板中的include标签 $find = preg_match_all('/'.$this->config['taglib_begin'].'include\s(.+?)\s*?\/'.$this->config['taglib_end'].'/is',$content,$matches); if($find) { for($i=0;$i<$find;$i++) { $include = $matches[1][$i]; $array = $this->parseXmlAttrs($include); $file = $array['file']; unset($array['file']); $content = str_replace($matches[0][$i],$this->parseIncludeItem($file,$array,$extend),$content); } } return $content; }
然后我们就可以放心大胆的使用模板常量做为模板继承或Include的路径了!
定义模板常量其实也有小技巧,参考我的另一篇文章