视图概述
视图(View)是MVC框架中用户看到并与之交互的界面部分。StartMVC提供了一个轻量级但功能强大的模板引擎,支持原生PHP语法与简洁的模板标签,兼顾了开发效率和运行性能。
创建视图
视图文件默认以.php结尾,命名规则为控制器_方法.php,默认位于/模块/view目录下。可以自定义模板后缀名,在/config/view.php进行配置。
return [
'suffix' => '.php', // 模板文件后缀,默认php,可配置为html,.blade, .tpl, .twig, .phtml之类的
]; 多主题支持
StartMVC支持多风格模板,可在config/common.php中设置:
'theme' => '', //指定模板子目录,例如'default',为空时模板文件直接在view下调用视图
在控制器中使用$this->display()方法调用视图:
namespace app\home\controller;
use startmvc\core\Controller;
class IndexController extends Controller {
function indexAction(){
// 默认输出到home模块下的view/index_index.php
$this->display();
// 输出到home模块下的view/view.php
$this->display('view');
// 输出到admin模块下的view/public/view.php
$this->display(['Admin', 'public/view']);
//支持指定后缀名
$this->display('test.html');
}
}获取视图内容但不输出
如果您需要获取渲染结果但不直接输出,可以使用fetch方法:
// 获取渲染内容
$content = $this->fetch('index');
// 对内容进行处理
$content = str_replace('old', 'new', $content);
// 手动输出
echo $content;
布局(Layout)
页面通常都有公共外壳:页头、导航、页脚、样式与脚本引用。如果每个视图都写一遍,改一次页脚就得动所有文件。布局把外壳抽成一个独立的模板文件,视图里只写正文,渲染时由框架自动套上。
布局默认关闭。在 config/view.php 里填上布局模板名即可开启:
return [
'suffix' => '.php',
'tpl_safe_mode' => false,
'layout' => 'layout', // 布局模板名,留空 = 关闭布局(默认)
];布局模板与视图放在同一目录(app/模块/view/),正文位置写 {$__content__} 输出:
// app/home/view/layout.php
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>{$title} - 站点名称</title>
</head>
<body>
{include common/header}
<main class="main">
{$__content__}
</main>
{include common/footer}
</body>
</html>视图只写正文,完全不用管外壳:
// app/home/view/index/index.php
<h1>{$title}</h1>
<ul>
{foreach $list as $item}
<li>{$item.name}</li>
{/foreach}
</ul>控制器不需要为布局改任何代码,display() 会自动套布局:
class IndexController extends Controller
{
public function index()
{
$this->assign('title', '商品列表');
$this->assign('list', $this->model('Goods')->select());
$this->display(); // 整页输出,自动套上布局
}
}取片段时不套布局
Ajax 或局部刷新只需要正文,用 fetch() 取内容,它强制不套布局——同一个视图文件不用为了 Ajax 再抄一份:
// 返回片段(不套布局),交给前端渲染
return $this->json($this->fetch('index'));运行时换壳
前台和后台可以共用同一份视图,只在渲染前换布局:
$this->layout('admin_layout'); // 换成后台布局
$this->display();
$this->layout(''); // 关闭布局(本次请求)布局文件的位置与主题
布局模板名是相对当前模块 view/ 目录的路径,可以放在子目录里,例如 'layout' => 'layout/main' 对应 app/home/view/layout/main.php。布局的解析同样跟随主题,所以配置了主题时,不同主题各有一份自己的布局。
与 include 的区别
两者互补:{include} 在编译期把被引入文件的内容内联进当前模板,适合页头页脚这类固定片段;布局在运行时把渲染好的正文包进外壳,好处是同一个视图既能整页输出、又能取片段,而且不必在每个视图里重复写引入语句。
布局模板里可以正常使用所有模板标签({include}、{foreach}、{$var} 等);控制器 assign() 的变量在布局里也能直接取到,不需要额外传递。
视图赋值
传递变量到视图
在控制器中使用assign方法传递变量到视图:
// 单个变量赋值
$this->assign('title', 'StartMVC框架');
// 批量赋值
$data = [
'title' => 'StartMVC框架',
'users' => [
['name' => '小明', 'age' => 21],
['name' => '小红', 'age' => 20]
]
];
$this->assign($data);
// 支持链式调用
$this->assign('title', '网站标题')
->assign('keywords', 'PHP,MVC,轻量级')
->display();
// 在display时传递变量
$this->display('index', ['time' => time()]);
在视图中使用变量
视图中有两种方式使用变量:
1. PHP原生语法:
姓名:,年龄:
2. 模板标签语法:
{$title}
{loop $users $user}
姓名:{$user.name},年龄:{$user.age}
{/loop}