模板与逻辑分离

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

thinkphp 模板 php 代码
(图片来源网络,侵删)

ThinkPHP 模板中的 PHP 代码,主要用于:

  1. 输出变量:将控制器传递过来的数据显示在页面上。
  2. 简单条件判断:根据变量值决定显示哪部分内容。
  3. 循环遍历:展示列表数据。
  4. 包含其他模板:复用模板片段。

输出变量

这是最常用、最基础的功能,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 模板 php 代码
(图片来源网络,侵删)

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 代码,使模板更整洁。

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}

核心建议

  1. 保持模板简洁:模板文件里只应该有 HTML 和 ThinkPHP 的模板标签。
  2. 逻辑前置:所有复杂的数据处理、计算、条件判断逻辑都放在控制器或模型中完成。
  3. 善用助手函数:如 {:url()}, {:input()}, {:config()} 等,它们能让你的模板更安全、更简洁。
  4. 理解标签库:花时间熟悉 ThinkPHP 的标签库(volist, if, switch 等),它们是 ThinkPHP 模板的核心优势。

遵循这些原则,你的项目将更容易维护、扩展和协作。