thinkphp模板编译后的php文件默认存于runtime/template/目录下,tp6路径为runtime/template/{md5(模板路径)}/,tp5.1为runtime/template/{hash}/;可通过配置template.cache_path自定义位置。

ThinkPHP 模板编译后的 PHP 文件在哪
ThinkPHP 的模板不是直接解释执行的,而是先编译成原生 PHP 文件再 require 执行。这个编译结果默认存在 runtime/cache/ 或 runtime/template/ 下,路径取决于版本和配置。
常见错误现象:改了模板但页面没变,或者报错提示指向一个奇怪的 PHP 文件(比如 xxx.tpl.php),其实那就是编译产物。
- ThinkPHP 6 默认路径是
runtime/template/{md5(模板路径)}/,里面是带长随机名的.php文件 - ThinkPHP 5.1 的路径通常是
runtime/template/{hash}/,文件名类似2f7a8b1c.php - 如果
app_debug = false,缓存可能不自动更新,得手动删整个runtime/template/目录 - 注意
template.cache_path配置项可自定义位置,别只盯死默认路径
怎么让 TP 输出编译后的 PHP 代码而不是执行它
想看模板到底被翻译成了什么,最直接的办法是「拦截编译输出」——不让它写入缓存文件,而是直接 echo 出来。
核心思路:在模板引擎初始化后、fetch() 调用前,替换掉 think\Template 的 compiler() 方法,或临时重写 parseTemplateContent() 的返回逻辑。
- TP6 中可在
app/common.php或控制器里加临时调试代码:app('view')->getEngine()->setOptions(['strip_space' => false, 'cache' => false]);再配合关闭缓存,能减少干扰 - 更稳妥的做法是,在
think\Template::compiler()方法内打日志或dump($content),但需确认是否在调试模式下(否则可能被屏蔽) - 别依赖浏览器查看源码——编译结果是服务端执行的中间 PHP,不会出现在 HTML 源码里
- 注意:开启
display_errors并设为E_ALL,否则语法错误可能静默失败,只显示空白页
为什么改了模板但编译文件没更新
不是模板引擎“卡住”了,而是 ThinkPHP 默认做了三重校验:文件修改时间、模板内容哈希、以及运行时缓存开关状态。任一环节不满足,就不会重新编译。
典型表现是:改完 index.html,刷新页面还是旧内容,甚至删了 runtime/template/ 也没用。
-
app_debug = false时,模板缓存强制开启且不检查 mtime,必须清空缓存或设为true - 某些 IDE(如 PHPStorm)保存时用的是原子写入(先写 temp 再 rename),导致文件 inode 变了但 mtime 没触发更新,TP 会漏判
- Linux 下挂载的 Windows 共享目录(如 Samba)可能不支持精确 mtime,需显式设置
'type' => 'must_rebuild'缓存策略 - TP6 的
template.cache_prefix如果用了固定字符串,会导致不同环境共用同一缓存 key,误判为“无需重编译”
编译缓存文件里那些 echo 和 <?php 是怎么来的
ThinkPHP 模板语法(如 {:func()}、{volist name="list"})在编译阶段会被正则或 AST 方式替换成标准 PHP 语句。这个过程由 think\Template\TagLib 和 think\Template\Compiler 协同完成。
比如 {volist name="data" id="vo"} 最终变成 foreach($data as $vo){;{:date('Y-m-d')} 变成 <?php echo date('Y-m-d'); ?>。
- 所有标签都会被转义成 PHP 块,所以编译文件本质就是合法 PHP,可直接用
php -l检查语法 -
{literal}区块内的内容原样保留,不参与解析,适合放 JS 或复杂 PHP 片段 - TP6 开始支持
template.syntax配置自定义定界符,但编译器仍按固定规则识别,改了定界符却没同步更新编译逻辑就会出错 - 性能上,一次编译多次执行,所以首次访问慢;但若频繁清缓存或关缓存,反而比原生 PHP 还慢——因为每次都在重复解析+生成
真正难调的不是“怎么看到编译结果”,而是当编译后 PHP 报错时,错误行号对不上模板行号。这时候得打开 template.debug_parsing(TP6)或手动在 Compiler::parseTag() 里加 trace,不然光看那个 200 行的缓存文件,根本找不到哪句 {if} 少了 {/if}。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











