<if>等XML标签原样输出,是因为模板引擎未识别:常见原因包括写在<php>或<script>内未用<literal>包裹、自定义标签库未正确注册、$tags未声明、定界符修改导致匹配失败;<literal>仅禁用解析,不修复语法错误,且不支持嵌套、对空格敏感。

模板里写了个 <if> 却直接显示在页面上,不是执行逻辑而是原样吐出来——这不是 bug,是标签冲突或解析被跳过。
为什么 <if>、<foreach> 这类 XML 标签会原样输出
ThinkPHP 的 XML 标签(如 <if>、<volist>)必须由模板引擎主动识别并转换为 PHP 代码;一旦没被识别,整段就当纯文本透传。常见原因有:
- 标签写在
<php>或<script>块里,而没加<literal>包裹 - 自定义标签库未正确注册:类没继承
think\template\TagLib、类名不以TagLib结尾、没放在app\taglib\目录下 -
$tags数组里没声明该标签键名(必须全小写,比如'if' => ['attr' => 'condition']) - 模板定界符被改过,但 XML 标签仍按默认
{}解析,导致匹配失败
<literal> 不是“万能包裹”,它只禁用解析,不修复语法错误
<literal> 的作用很明确:告诉模板引擎“这段内容别碰,原封不动输出”。但它不会帮你校验标签是否合法,也不会让错位的 </if> 自动闭合。
- 写成
<literal><if condition="$a">xxx</if></literal>→ 页面显示的就是文字<if condition="$a">xxx</if> - 写成
<php><literal>echo '{$name}';</literal></php>→ 输出的是{$name}字符串,而非变量值 - JS 代码块外层加
<literal>很常见,但若 JS 里又嵌了{$xxx},这些仍会被解析(因为<literal>只作用于其直接子内容)
什么时候必须用 <literal>,而不是改写法
不是所有冲突都靠重写逻辑解决;有些场景绕不开原始标签字符串,这时 <literal> 是唯一安全选择:
立即学习“PHP免费学习笔记(深入)”;
- 在文档示例页展示 ThinkPHP 模板语法本身,比如写教程时要呈现
{:dump($data)} - 前端 JS 中动态拼接模板字符串,例如
html += '<if condition="'+cond+'">...</if>',需确保引号和结构不被提前解析 - 调试阶段临时屏蔽某段 XML 标签逻辑,又不想删代码——加一对
<literal>最快 -
<php>标签内含{$Think.xxx}类引用,不加<literal>会导致$Think被误解析为变量输出空值
容易被忽略的细节:<literal> 不支持嵌套,且对空格敏感
<literal> 是单层透传机制,没有嵌套能力。另外,它的行为受前后空白影响:
- 写成
<literal> <if>xxx</if> </literal>(首尾带空格),空格会被保留并输出,可能破坏 HTML 结构 -
<literal>和</literal>必须成对出现,漏写闭合标签会导致后续所有模板内容都被原样输出 - 它不能替代注释:注释用
{/* ... */}或{// ...},<literal>是输出内容,不是隐藏内容 - ThinkPHP 6 开始,
<literal>在<xml>或<svg>等非 HTML 上下文中可能被浏览器解析异常,此时建议改用{literal}...{/literal}的花括号风格(如果模板配置允许)



















