本文目录导读:

在ThinkPHP框架中,视图与模板引擎是MVC架构中非常重要的组成部分,下面我来详细介绍ThinkPHP的视图与模板引擎机制。
视图基础概念
视图的主要职责
- 展示数据
- 分离业务逻辑与表现层
- 支持模板继承与复用
模板引擎配置
在config/view.php中配置:
return [
// 模板引擎类型使用Think
'type' => 'Think',
// 默认模板渲染规则
'default_theme' => '',
// 模板目录名
'view_dir_name' => 'view',
// 模板后缀
'view_suffix' => 'html',
// 模板常量
'tpl_begin' => '{',
'tpl_end' => '}',
// 模板替换
'tpl_replace' => [
'__ADMIN__' => '/static/admin',
'__PUBLIC__' => '/static',
],
// 模板缓存
'tpl_cache' => true,
// 模板编译缓存
'tpl_deny_php' => false,
];
模板渲染方法
控制器中渲染模板
namespace app\controller;
use think\facade\View;
class User
{
// 使用View类
public function index()
{
View::assign('name', '张三');
View::assign('age', 25);
return View::fetch();
}
// 使用fetch方法
public function detail()
{
// 分配单个变量
$this->assign('user', ['name' => '李四', 'age' => 30]);
// 批量分配
$this->assign([
'title' => '用户详情',
'data' => $data
]);
// 渲染指定模板
return $this->fetch('user/detail');
}
// 使用view助手函数
public function profile()
{
return view('profile', [
'name' => '王五',
'email' => 'wangwu@example.com'
]);
}
}
模板文件命名规范
view/
├── index/ # 控制器目录
│ ├── index.html # 对应index方法
│ ├── about.html # 对应about方法
└── user/
├── index.html
└── detail.html
模板语法详解
变量输出
<!-- 普通变量 -->
{$name}
{$user.name}
{$user['name']}
<!-- 默认值 -->
{$name|default='未命名'}
{$email|default='暂无邮箱'}
<!-- 运算符 -->
{$a + $b}
{$a * $b}
{$a > $b ? '大于' : '小于'}
<!-- 函数调用 -->
{:time()}
{:strtoupper($name)}
{:date('Y-m-d', $time)}
表达式与运算
<!-- 算术运算 -->
{$score + 10}
{$price * 0.8}
<!-- 比较运算 -->
{$age >= 18 ? '成年' : '未成年'}
<!-- 逻辑运算 -->
{$flag && $status}
{$flag || $status}
<!-- 三元运算 -->
{$condition ? '真' : '假'}
循环标签
<!-- foreach 循环 -->
{foreach $list as $key=>$value}
<tr>
<td>{$key}</td>
<td>{$value.name}</td>
<td>{$value.price}</td>
</tr>
{/foreach}
<!-- volist 循环(ThinkPHP特有) -->
{volist name="list" id="item"}
<li>{$item.title}</li>
{/volist}
<!-- 循环控制 -->
{foreach $list as $item}
{if $item@first}第一个{/if}
{if $item@last}最后一个{/if}
{if $item@iteration % 2}偶数行{/if}
{/foreach}
分支判断
<!-- if 判断 -->
{if $status == 1}
启用中
{elseif $status == 0}
已禁用
{else}
状态未知
{/if}
<!-- switch 判断 -->
{switch $type}
{case value="1"}类型一{/case}
{case value="2|3"}类型二或三{/case}
{default/}其他类型
{/switch}
<!-- 条件判断 -->
{if condition="($name == 'admin') AND ($age > 20)"}
管理员且年龄大于20
{/if}
模板继承
基础模板(layout.html)
<!-- application/view/layout.html -->
<!DOCTYPE html>
<html>
<head>{block name="title"}默认标题{/block}</title>
</head>
<body>
<div class="header">
网站头部
</div>
<div class="content">
{block name="content"}默认内容{/block}
</div>
<div class="footer">
网站底部
</div>
</body>
</html>
子模板继承
<!-- 子模板 -->
{extend name="layout"}
{block name="title"}用户列表{/block}
{block name="content"}
<table>
<tr>
<th>ID</th>
<th>用户名</th>
</tr>
{foreach $users as $user}
<tr>
<td>{$user.id}</td>
<td>{$user.username}</td>
</tr>
{/foreach}
</table>
{/block}
模板引入与加载
<!-- 引入外部模板 -->
{include file="public/header" /}
{include file="public/footer" /}
<!-- 引入时传递参数 -->
{include file="public/nav" title="导航" /}
<!-- 加载静态资源 -->
{css href="/static/css/style.css" /}
{js href="/static/js/main.js" /}
<!-- 图片输出 -->
<img src="__STATIC__/images/logo.png">
模板引擎高级特性
模板助手函数
// 控制器中
return view('index', [
'time' => time(),
'html' => '<b>加粗文本</b>'
]);
<!-- 模板中使用函数 -->
{:date('Y-m-d', $time)}
{:strip_tags($html)}
{:mb_substr($content, 0, 100)}
<!-- 变量修饰符 -->
{$content|nl2br}
{$date|date='Y年m月d日'}
<!-- 防御XSS -->
{$content|htmlspecialchars}
{$content|htmlentities}
模板布局
<!-- 定义布局 -->
{layout name="layout" /}
<!-- 使用布局 -->
{layout name="layout" replace="[__CONTENT__]"}
模板缓存控制
<!-- 禁用缓存 -->
{cache name="key" expires="0"}
动态内容
{/cache}
<!-- 多级缓存 -->
{cache name="user_$id"}
{foreach $users as $user}
{$user.name}
{/foreach}
{/cache}
模板安全与性能
安全防护
// 开启HTML过滤 'default_filter' => 'htmlspecialchars', // 禁止PHP标签 'tpl_deny_php' => true, // 模板编译时自动过滤 'auto_escape' => true,
性能优化
// 开启模板缓存 'tpl_cache' => true, // 设置缓存时间 'tpl_cache_time' => 3600, // 模板编译目录 'view_compile' => runtime_path() . 'temp/',
完整示例
控制器
namespace app\controller;
use think\facade\View;
class Product
{
public function list()
{
$products = [
['id' => 1, 'name' => '手机', 'price' => 3000],
['id' => 2, 'name' => '电脑', 'price' => 5999],
['id' => 3, 'name' => '平板', 'price' => 2500],
];
View::assign([
'products' => $products,
'title' => '产品列表',
'user' => ['is_admin' => 1]
]);
return View::fetch('list');
}
}
模板文件(view/product/list.html)
{extend name="layout"}
{block name="title"}{$title}{/block}
{block name="content"}
<div class="product-list">
{if $user.is_admin}
<div class="admin-toolbar">
<a href="{:url('product/add')}">新增产品</a>
</div>
{/if}
<table>
<tr>
<th>ID</th>
<th>产品名称</th>
<th>价格</th>
<th>操作</th>
</tr>
{foreach $products as $product}
<tr>
<td>{$product.id}</td>
<td>{$product.name}</td>
<td>¥{$product.price|number_format=2}</td>
<td>
<a href="{:url('product/edit', ['id' => $product.id])}">编辑</a>
<a href="{:url('product/delete', ['id' => $product.id])}"
onclick="return confirm('确定删除?')">删除</a>
</td>
</tr>
{/foreach}
</table>
</div>
{/block}
通过这些示例可以看出,ThinkPHP的模板引擎提供了强大而灵活的功能,能够满足各种复杂的页面渲染需求,记得根据实际项目选择合适的语法和功能来使用。