模板与逻辑分离
首先要明确一个重要原则:模板文件(.html)主要负责展示数据,而复杂的业务逻辑(如数据库操作、循环判断、计算等)应该放在控制器(Controller)或模型(Model)中完成。

(图片来源网络,侵删)
ThinkPHP 模板中的 PHP 代码,主要用于:
- 输出变量:将控制器传递过来的数据显示在页面上。
- 简单条件判断:根据变量值决定显示哪部分内容。
- 循环遍历:展示列表数据。
- 包含其他模板:复用模板片段。
输出变量
这是最常用、最基础的功能,ThinkPHP 提供了多种变量输出标签。
普通变量
假设在控制器中你传递了以下变量:
// 在控制器中
namespace app\controller;
use think\facade\View;
class Index
{
public function index()
{
$name = 'ThinkPHP';
$age = 10;
View::assign('name', $name);
View::assign('age', $age);
return View::fetch('index'); // 渲染 app/view/index/index.html 模板
}
}
在模板文件 index.html 中,你可以这样输出:

(图片来源网络,侵删)
ThinkPHP 5.x/6.x 语法(推荐)
{$name}:输出变量name的值。{$age + 1}:直接进行简单运算。{$user.name}:输出数组或对象的属性($user['name'])。{$user['name']}:直接输出数组的键值。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">ThinkPHP 模板示例</title>
</head>
<body>
<h1>你好, {$name}!</h1>
<p>你今年 {$age} 岁了,明年就 {$age + 1} 岁了。</p>
</body>
</html>
系统变量
可以输出 PHP 的超全局变量,如 $_GET, $_POST, $_SERVER, $_SESSION, $_COOKIE 等。
<p>当前请求的控制器和方法是: {:request()->controller() . '/' . request()->action()}</p>
<p>获取 GET 参数 id: {:input('id')}</p> <!-- 更推荐使用 input 助手函数 -->
<p>获取 SERVER 变量 HTTP_HOST: {$_SERVER['HTTP_HOST']}</p>
注意:直接输出
$_GET或$_POST可能存在安全风险,推荐使用input()助手函数来获取和过滤输入。
使用标签(Tag ThinkPHP 5.x/6.x)
ThinkPHP 提供了一套强大的标签库来替代复杂的原生 PHP 代码,使模板更整洁。

(图片来源网络,侵删)
if 条件判断
{if condition="$age > 18"}
<p>你已经成年了。</p>
{else /}
<p>你还未成年。</p>
{/if}
<!-- 更复杂的判断 -->
{if condition="$age > 18 && $sex == '男'"}
<p>成年男性。</p>
{elseif condition="$age > 18 && $sex == '女'"}
<p>成年女性。</p>
{else /}
<p>未成年。</p>
{/if}
volist 循环遍历
这是最常用的循环标签,用于遍历数组。
假设控制器传递了一个用户列表:
// 在控制器中
$users = [
['id' => 1, 'name' => '张三', 'email' => 'zhangsan@example.com'],
['id' => 2, 'name' => '李四', 'email' => 'lisi@example.com'],
['id' => 3, 'name' => '王五', 'email' => 'wangwu@example.com'],
];
View::assign('users', $users);
在模板中:
<table border="1">
<tr>
<th>ID</th>
<th>姓名</th>
<th>邮箱</th>
</tr>
<volist name="users" id="user">
<tr>
<td>{$user.id}</td>
<td>{$user.name}</td>
<td>{$user.email}</td>
</tr>
</volist>
</table>
name="users":要循环的变量名。id="user":循环中当前元素的临时变量名。
其他常用循环标签:
foreach:用法类似volist,但更接近 PHP 原生语法。<foreach name="users" item="user"> <p>{$user.name} - {$user.email}</p> </foreach>for:标准 for 循环。<for start="1" end="10" step="1" name="i"> <p>当前数字是: {$i}</p> </for>
switch 多分支判断
<switch name="user.level">
<case value="1">普通会员</case>
<case value="2">VIP会员</case>
<case value="3">SVIP会员</case>
<default />普通用户
</switch>
include 包含模板
用于将一个公共的模板片段(如页头、页脚、导航栏)包含进来。
假设有一个公共模板 public/header.html:
<!-- public/header.html -->
<header>
<h1>网站标题</h1>
<nav>
<a href="/">首页</a>
<a href="/about">关于我们</a>
</nav>
</header>
在主模板 index.html 中:
<!DOCTYPE html>
<html lang="zh-CN">
<head>首页</title>
</head>
<body>
<!-- 包含页头 -->
{include file="public/header" /}
<main>
<h2>这里是主页内容</h2>
<!-- ... 其他内容 ... -->
</main>
<!-- 包含页脚 -->
{include file="public/footer" /}
</body>
</html>
原生 PHP 代码(不推荐,但可用)
在极少数情况下,你可能需要在模板中直接写 PHP 代码,ThinkPHP 提供了标签支持。
php
{php}
// 在这里写原生 PHP 代码
$now = date('Y-m-d H:i:s');
echo "当前服务器时间是: " . $now;
{/php}
literal
如果你想将一段文本原样输出,而不被模板引擎解析,可以使用 literal 标签,这在包含 JavaScript 或 CSS 代码时特别有用。
<literal>
<script>
function myFunction() {
// 这里的 { 和 } 不会被当作模板标签解析
var str = "这是一个 {literal} 标签的 {/literal} 示例";
alert(str);
}
</script>
</literal>
使用原生 PHP 代码的缺点
- 破坏 MVC 分离:将逻辑混入视图,使代码难以维护。
- 安全性降低:增加了 XSS(跨站脚本攻击)的风险,需要对变量进行更严格的过滤。
- 性能影响:模板引擎无法对原生 PHP 代码进行优化。
- 可读性差:模板文件中夹杂着 PHP 代码,显得混乱。
常用模板函数和助手
ThinkPHP 提供了一些内置函数和助手来简化模板操作。
{:function()}:执行一个函数并输出结果。{:date('Y-m-d', time())} <!-- 输出当前日期 -->
{:md5('hello')} <!-- 输出 hello 的 MD5 值 -->
{:url()}:生成 URL,这是非常重要的一个助手函数。<a href="{:url('user/profile', ['id' => 123])}">查看我的资料</a>
{:config('app.name')}:获取配置项的值。
{:session('user.name')}:获取 Session 值。
{:csrf_field()}:生成 CSRF 令牌表单,用于表单提交安全。
总结与最佳实践
功能场景
推荐方式
示例
输出简单变量
{$var}
{$name}
输出数组/对象属性
{$user.name}
{$user['name']}
简单条件判断
{if} / {else} / {/if}
{if condition="$age > 18"}...{/if}
循环数组
{volist}
{volist name="users" id="user"}...{/volist}
包含公共模板
{include}
{include file="public/header" /}
生成 URL
{:url()}
{:url('user/index')}
执行函数/获取配置
{:func()}
{:date('Y-m-d')}
原生 PHP 代码
尽量避免,仅在特殊情况下使用
{php}...{/php}
核心建议:
- 保持模板简洁:模板文件里只应该有 HTML 和 ThinkPHP 的模板标签。
- 逻辑前置:所有复杂的数据处理、计算、条件判断逻辑都放在控制器或模型中完成。
- 善用助手函数:如
{:url()}, {:input()}, {:config()} 等,它们能让你的模板更安全、更简洁。
- 理解标签库:花时间熟悉 ThinkPHP 的标签库(
volist, if, switch 等),它们是 ThinkPHP 模板的核心优势。
遵循这些原则,你的项目将更容易维护、扩展和协作。
{php}
// 在这里写原生 PHP 代码
$now = date('Y-m-d H:i:s');
echo "当前服务器时间是: " . $now;
{/php}
literal
如果你想将一段文本原样输出,而不被模板引擎解析,可以使用 literal 标签,这在包含 JavaScript 或 CSS 代码时特别有用。
<literal>
<script>
function myFunction() {
// 这里的 { 和 } 不会被当作模板标签解析
var str = "这是一个 {literal} 标签的 {/literal} 示例";
alert(str);
}
</script>
</literal>
使用原生 PHP 代码的缺点
- 破坏 MVC 分离:将逻辑混入视图,使代码难以维护。
- 安全性降低:增加了 XSS(跨站脚本攻击)的风险,需要对变量进行更严格的过滤。
- 性能影响:模板引擎无法对原生 PHP 代码进行优化。
- 可读性差:模板文件中夹杂着 PHP 代码,显得混乱。
常用模板函数和助手
ThinkPHP 提供了一些内置函数和助手来简化模板操作。
{:function()}:执行一个函数并输出结果。{:date('Y-m-d', time())} <!-- 输出当前日期 -->
{:md5('hello')} <!-- 输出 hello 的 MD5 值 -->
{:url()}:生成 URL,这是非常重要的一个助手函数。<a href="{:url('user/profile', ['id' => 123])}">查看我的资料</a>
{:config('app.name')}:获取配置项的值。
{:session('user.name')}:获取 Session 值。
{:csrf_field()}:生成 CSRF 令牌表单,用于表单提交安全。
总结与最佳实践
功能场景
推荐方式
示例
输出简单变量
{$var}
{$name}
输出数组/对象属性
{$user.name}
{$user['name']}
简单条件判断
{if} / {else} / {/if}
{if condition="$age > 18"}...{/if}
循环数组
{volist}
{volist name="users" id="user"}...{/volist}
包含公共模板
{include}
{include file="public/header" /}
生成 URL
{:url()}
{:url('user/index')}
执行函数/获取配置
{:func()}
{:date('Y-m-d')}
原生 PHP 代码
尽量避免,仅在特殊情况下使用
{php}...{/php}
核心建议:
- 保持模板简洁:模板文件里只应该有 HTML 和 ThinkPHP 的模板标签。
- 逻辑前置:所有复杂的数据处理、计算、条件判断逻辑都放在控制器或模型中完成。
- 善用助手函数:如
{:url()}, {:input()}, {:config()} 等,它们能让你的模板更安全、更简洁。
- 理解标签库:花时间熟悉 ThinkPHP 的标签库(
volist, if, switch 等),它们是 ThinkPHP 模板的核心优势。
遵循这些原则,你的项目将更容易维护、扩展和协作。
如果你想将一段文本原样输出,而不被模板引擎解析,可以使用 literal 标签,这在包含 JavaScript 或 CSS 代码时特别有用。
<literal>
<script>
function myFunction() {
// 这里的 { 和 } 不会被当作模板标签解析
var str = "这是一个 {literal} 标签的 {/literal} 示例";
alert(str);
}
</script>
</literal>
使用原生 PHP 代码的缺点
- 破坏 MVC 分离:将逻辑混入视图,使代码难以维护。
- 安全性降低:增加了 XSS(跨站脚本攻击)的风险,需要对变量进行更严格的过滤。
- 性能影响:模板引擎无法对原生 PHP 代码进行优化。
- 可读性差:模板文件中夹杂着 PHP 代码,显得混乱。
常用模板函数和助手
ThinkPHP 提供了一些内置函数和助手来简化模板操作。
{:function()}:执行一个函数并输出结果。{:date('Y-m-d', time())} <!-- 输出当前日期 --> {:md5('hello')} <!-- 输出 hello 的 MD5 值 -->{:url()}:生成 URL,这是非常重要的一个助手函数。<a href="{:url('user/profile', ['id' => 123])}">查看我的资料</a>{:config('app.name')}:获取配置项的值。{:session('user.name')}:获取 Session 值。{:csrf_field()}:生成 CSRF 令牌表单,用于表单提交安全。
总结与最佳实践
| 功能场景 | 推荐方式 | 示例 |
|---|---|---|
| 输出简单变量 | {$var} |
{$name} |
| 输出数组/对象属性 | {$user.name} |
{$user['name']} |
| 简单条件判断 | {if} / {else} / {/if} |
{if condition="$age > 18"}...{/if} |
| 循环数组 | {volist} |
{volist name="users" id="user"}...{/volist} |
| 包含公共模板 | {include} |
{include file="public/header" /} |
| 生成 URL | {:url()} |
{:url('user/index')} |
| 执行函数/获取配置 | {:func()} |
{:date('Y-m-d')} |
| 原生 PHP 代码 | 尽量避免,仅在特殊情况下使用 | {php}...{/php} |
核心建议:
- 保持模板简洁:模板文件里只应该有 HTML 和 ThinkPHP 的模板标签。
- 逻辑前置:所有复杂的数据处理、计算、条件判断逻辑都放在控制器或模型中完成。
- 善用助手函数:如
{:url()},{:input()},{:config()}等,它们能让你的模板更安全、更简洁。 - 理解标签库:花时间熟悉 ThinkPHP 的标签库(
volist,if,switch等),它们是 ThinkPHP 模板的核心优势。
遵循这些原则,你的项目将更容易维护、扩展和协作。
