视图
在index文件夹下面新建一个view文件夹,然后在新建一个index文件夹(与控制器中类的名字一致【小写】)新建一个index.html(与方法 名一致),作为视图输出的默认引擎
- 继承controller类,在index控制器中use think\controller 类,然后Index类继承controller类,使用控制器中的方法时会调用视图中的模板文件
use think\Controller;
class Index extends Controller
{
public function index()
{
$name='GG';
$email='GG@gmail.com';
$this->assign('name',$name);
$this->assign('email',$email);
return $this->fetch();
$this->db();
}
- 在模板文件中调用数据
{$name}
<hr>
{$email}
- 在fetch中不配置文件时,会自动定位到默认模板/view/index/index.html(view/控制器名/方法名),传入一个test后会定义到view/index/test(/view/控制器名/传入名)
return $this->fetch('test');
- fetch还可以跨模块调用模板(/view/user/user.html)
return $this->fetch('user/user')
- fetch也可以直接传入模板变量,第一个参数是模板名,第二个是传入的数据
return $this->fetch('index/index',[
'name'=>'Haha',
'email'=>'haha@gmail.com'
]);
- 使用助手函数view渲染输出(和fetch类似)
return view('index/index',[
'name'=>'Haha',
'email'=>'haha@gmail.com'
]);
模板
ThinkPHP内置了一个基于XML的模板引擎
- 模板文件就是视图目录下的html文件,普通变量输出{Think}(以$Think开头) ,还有配置输出
常量输出:在class外部使用define定义常量的名称和值,然后再在模板中使用
define('APP_PA','自定义常量值');
{$Think.APP_PA}
- 使用函数,在模板中使用函数,例如使用md5加密变量
{$name|md5}
- 如果一个函数需要调用多个函数,第一个参数是y-m-d,第二个参数是前面的$ctime,用###标志变量的位置;还可以使用多个函数过滤,使用多个|分割即可
{$ctime|date="y-m-d G:i:s",###}
或者也可以使用多个函数嵌套的方法进行多次过滤
{:substr(strtoupper(md5($name)),0,3)}
原样输出
- 使用literal标签,会原样输出$name标签,而不会输出具体数据
{literal}
{$name}
{/literal}
- 代码注释使用{/这里是注释/};注释符号和大括号之间不能有空格
模板布局
- 全局配置方式;开启模板布局,在开启layout_on模块之前会(fetch和view)默认渲染/view/index/index.html文件,开启之后会渲染/view/layout.html,模板布局和其他模板类似,但是有一个输出替换变量{CONTENT},在读取layout模板之后,会解析index.html文件,然后会把解析的内容替换{CONTENT},而index.html文件中也就不再需要html标签
'template' => [
'layout_on' => true,
'layout_name' => 'layout',
]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板布局</title>
</head>
<body>
<div style="background-color:aqua;height: 200px;width: auto"></div>
{__CONTENT__}
<div style="background-color:darkslategrey;height: 200px;width: auto"></div>
</body>
</html>
- 如果不需要使用模板布局功能,就在模板文件的开头加上{NOLAYOUT}字符串,比如:如果在index.html文件中加入{NOLAYOUT},即使开启模板布局功能,也不会加载模板布局
- 模板标签的方式,不需要在配置文件设置任何参数,不需要开启layout;关闭模板布局,然后在index.html文件的开头加上layout,name表示需要加载的模板文件的名字
{layout name='layout'}
- 使用layout控制布局模板,在控制器中使用layout方法,layout方法中可以添加true/false选择是否开启模板布局,也可以传入布局的文件名称选择布局文件
$this->view->engine->layout(true);
return $this->fetch('index',[
'name'=>'SSS',
'ctime'=>time()
]);
模板的继承
- 模板的继承和类的继承类似,定义基础的模块和相关的区块,子模块就可以对这些区块进行重载,区块由
{block}{/block}组成,新建一个base文件作为基础的模块,在index.html中使用模板的继承,此时index模块的样式完全是base中负模块的样式;子模块的其他内容不会显示
{block name='head'}
<div style="width: auto;height: 100px;background-color:paleturquoise;"><h2>基础头部信息</h2></div>
{/block}
<hr>
{block name='footer'}
<div style="width: auto;height: 100px;background-color:dimgrey;"><h2>基础底部信息</h2></div>
{/block}
{extend name='base'/}
- 在子模块中导入相同的结构,修改样式和内容信息,此时子模块为修改后的样式
{block name='head'}
<div style="width: auto;height: 100px;background-color:aqua;"><h2>子模板头部信息</h2></div>
{/block}
<hr>
{block name='footer'}
<div style="width: auto;height: 100px;background-color:lawngreen;"><h2>子模板底部信息</h2></div>
{/block}
{extend name='base'/}
- 内容合并,在子模块中使用{block}标签,此时会同时显示子模块的头部信息和基础模块的头部信息
{block name='head'}{__block__}
<div style="width: auto;height: 100px;background-color:aqua;"><h2>子模板头部信息</h2></div>
{/block}
<hr>
{block name='footer'}
<div style="width: auto;height: 100px;background-color:lawngreen;"><h2>子模板底部信息</h2></div>
{/block}
包含文件
- 一个模块中包含其他模块文件是使用include,包含的模板文件中不能使用模板布局和模板继承
{include file="../application/index/view/index/test.html" /}
内置标签
- 输出循环标签volist,offset表示从第几个数开始查询(不包括),length表示查询的长度,数据的条数
$list=UserModel::all();
$this->assign('list',$list);
echo gettype($list).'<hr>';
return $this->fetch();
<body>
{volist name='list' id='vo' offset='1' length='1'}
{$vo.id}===>{$vo.name}
{/volist}
</body>
路由规则
- 在route.php配置文件中配置路由规则,在首页返回的数据
Route::get('/',function(){
return 'Hello,world!';
});
- 访问一个哦控制器中的方法,在网址后直接输入 new /1(任意一个数据),就会访问index模块下面的news控制器中的list方法;第三个参数是请求方法(GET,POST等,请求类型必须大写)
Route::rule('new/:id','index/News/read');
也可以直接使用Route调用方法来规定请求方式
Route::get('new/:id','index/News/read');