IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> 【ThinkPHP6.x框架】(21)模板 -> 正文阅读

[PHP知识库]【ThinkPHP6.x框架】(21)模板

模版引擎驱动和赋值变量

引擎驱动? ? ? ??

????????MVC中,M(模型)和 ?C(控制器)是前面我们所了解的内容,而V(视图)就是页面。TP6.0默认不自带TT模版引擎,它作为一个可选的扩展给开发人员安装。也就是说,并不一定非要使用模板引擎的语法规则来开发V(视图)部分。如果不用模版引擎,可以在控制器通过require()方法引入PHP文件混编即可;如果要使用模版引擎,先创建一个用于测试模板引擎的控制器:Show.php,写入模版引擎的调用语法,来判断,是否已经安装了模板引擎扩展:

return View::fetch('index');                   //出现缺少驱动的错误

????????然后,安装如下驱动后,再刷新页面即可。

composer require topthink/think-view

赋值变量

????????在控制器区域,通过 ?assign()设置一个向模版提供变量的赋值操作(而模版区域,只需要通过{$name}的语法即可获取到控制器设置的值):

View::assign('name', 'Mr.Lee')

????????assign()方法,支持通过数组的方式,传递模版变量:

View::assign([
    'name' => 'Mr.Lee', 
    'age'  => 100
])

????????也可以直接通过fetch()方法的第二参数,直接用数组传递模版变量:

return View::fetch('index', [
    'name' => 'Mr.Lee', 
    'age'  => 100
]);

????????助手函数 ?view(),和 ?View::fetch()一样:

return view('index', [...])

????????可以使用 filter()方法,对所有模版的变量进行过滤操作:

return View::filter(function ($content) { 
    return strtoupper($content);
})->fetch('index');

return view('index')->filter(function ($content) { 
    return strtoupper($content);
});

模版引擎配置和渲染

模版配置

????????默认情况下,config/view.php就是默认模版引擎的配置文件。内部的配置注释写的非常清楚了,一般情况下,不需要任何改动;

模版渲染

????????除了在配置文件修改外,还可以在控制器端动态修改模版配置

View::config(['view_dir_name' => 'view2'])

????????默认情况下,调用的是本控制器的模版文件,也可以调用其它控制器的模版文件:

return View::fetch('Address/index');

????????如果你是多模块(多应用)模式下,也可以实现跨模块调用模版文件:

return View::fetch('admin@User/index')

????????如果直接在view 根目录下的模版文件,用一个斜杠来设定即可调用:

return View::fetch('/index')

????????如果想调用 ?public公共目录的模版文件,用../public后面跟着URL即可:

return View::fetch('../public/test/test)

?????????这种做法的调用方式,和模版引擎调用一样,只不过通信的数据获取方式有差异:

return View::engine('php')->fetch('index');

????????第二种原生PHP执行方式,在return之前设置的变量或者模版变量均无效。而是把所有的要传递的变量,通过 ?fetch()的第二个参数传递:

return View::engine('php')->fetch('index', [
    'name' => 'Mr.Lee', 
    'age'  => 100
]);

模版的变量输出

变量输出

????????当程序运行的时候,会在runtime/temp目录下生成一个编译文件,默认情况下,输出的模版变量会自动进行过滤,过滤函数默认如下:

<?php echo htmlentities($name); ?>

????????如果传递的值是数组,在模版区域可以使用$data.name这种形式输出:

$arr = ['name'=>'Mr.Lee', 'age'=>100];
return View::fetch('output', [ 
    'arr' => $arr
]);

{$arr.name}--{$arr.age}                        //模版数组变量输出 
<?php echo htmlentities($arr['name']); ?>      //编译文件

????????如果传递的值是对象,那么编译文件也会自动相应的对应输出方式:

public $name = 'Mr.Lee';
public $age = 'age'; 
const PI = 3.14;

return View::fetch('output', [ 
    'obj' => $this,
]);

{$obj->name}--{$obj->age}--{$obj->fn()}--{$obj::PI}
<?php echo htmlentities($obj->name); ?>        //编译文件

???

其它输出

????????如果输出的变量没有值,可以直接设置默认值代替:

{$data.name|default='没有姓名'}

????????系统变量有:$_SERVER、$_ENV、$_GET、$_POST、$_REQUEST、$_SESSION和$_COOKIE

????????对于注入Request对象,也可以直接在模版输出:

{$Request.get.id}
{$Request.param.name}
{$Request.host}

????????常量、配置信息等都可以通过$Think输出:

{$Think.const.PHP_VERSION} 
{$Think.PHP_VERSION}
{$Think.config.app.app_host} 
{$Think.config.session.name}

模版的函数和运算符

使用函数

????????控制器端先赋值一个密码的变量,模版区设置md5加密操作:

{$password|md5}

????????如果在某个字符,你不需要进行 HTML实体转义的话,可以单独使用 raw处理:

{$user['email']|raw}

????????系统还提供了一些固定的过滤方法,如下:

{$time|date='Y-m-d'}
{$number|format='%x'}

????????如果函数中,需要多个参数调用,直接用逗号隔开即可:

{$name|substr=0,3}

????????在模版中也支持多个函数进行操作,用|号隔开即可,函数从左到右依次执行:

{$password|md5|upper|substr=0,3}

????????你也可以在模版中直接使用 ?PHP的语法模式,该方法不会使用过滤转义:

{:substr(strtoupper(md5($password)), 0, 3)}

运算符

????????在模版中的运算符有+、-、*、/、%、++、--等:

{$number + $number}

????????如果模版中有运算符,部分函数不支持:

{$number + $number|default='没有值'}

????????模版也可以实现三元运算,包括其它写法:

{$name ? '正确' : '错误'}      //$name为  true返回正确,否则返回错误
{$name ?= '真'}                //$name为  true返回真
 
{$Request.get.name ?? '不存在'}    //??用于系统变量,没有值时输出
{$name ?: '不存在'}                //?:用于普通变量,没有值时输出

????????三元运算符也支持运算后返回布尔值判断:

{$a == $b ? '真' : '假'}

模版的循环标签

foreach循环

????????控制前端先通过模型把相应的数据列表给筛选出来:

$list = User::select();
    return View::fetch('loop', [ 
        'list' => $list
]);

????????在模版端使用对称的标签{foreach}...{/foreach}实现循环(注意,这里对象调用时:用->符号或用.符号均可正确实现数据显示):

{foreach $list as $key=>$obj}
<tr>
    <td>{$key}/{$obj->id}</td>         //{$obj.id}也行 
    <td>{$obj->username}</td>
    <td>{$obj->gender}</td>
    <td>{$obj->email}</td>
    <td>{$obj->price}</td>
    <td>{$obj->create_time}</td> 
</tr>
{/foreach}

volist循环

????????volist也是将查询得到的数据集通过循环的方式进行输出:

{volist name="list" id="obj"} 
<tr>
    <td>{$key}/{$obj->id}</td>            //{$obj.id}也行 
    <td>{$obj->username}</td>
    <td>{$obj->gender}</td>
    <td>{$obj->email}</td>
    <td>{$obj->price}</td>
    <td>{$obj->create_time}</td> 
</tr>
{/volist}

????????volist中的name属性表示数据总集,id属性表示当前循环的数据单条集。使用 offset属性和 length属性从第4条开始显示5条,这里下标从0开始。

{volist name="list" id="obj" offset='3' length='5'}

????????可以使用eq标签(下节课比较标签的知识点),来实现奇数或偶数的筛选数据:

{volist name="list" id="obj" mod="2"} 
{eq name='mod' value='0'}...

????????通过编译文件可以理解,mod=2表示索引除以2得到的余数是否等于0或1。如果余数设置为0,那么输出的即偶数,如果设置为1,则输出的是奇数,当然,切换到其它数字,也会有更多的排列效果。使用empty属性,可以当没有任何数据的时候,实现输出指定的提示:

{volist name="list" id="obj" empty="没有数据"}

????????使用key='k',让索引从1开始计算,不指定就用{$i},指定后失效:

{volist name='list' id='obj' key='k'}
    {$k}
{/volist}

for循环

????????for循环,顾名思义,通过起始和终止值,结合步长实现的循环:

{for start='1' end='100' comparison='lt' step='2' name='i'} 
    {$i}
{/for}

模版的比较和定义标签

比较标签

????????{eq}..{/eq}标签,比较两个值是否相同,相同即输出包含内容

{eq name='name' value='Mr.Lee'} 
    李先生
{/eq}

????????属性name里是一个变量,$符号可加可不加;而value里是一个字符串,如果value也需要是一个变量的话,那么value需要加上$后的变量:

{eq name='name2' value='$name2'}

????????这一组标签也支持 ?else操作,标签为:{else/}:

{eq name='name' value='Mr.Lee'}
    两个值相等 
{else/}
    两个值不等 
{/eq}

????????{eq}标签有一个别名标签:{equal},效果是一样的,所有比较标签如下:

?????????所有的标签都可以统一为{compare}标签使用,增加一个type方法指定即可:

{compare name='name' value='Mr.Lee' type='eq'}两个值相等{/compare}

?

定义标签

????????如果你想在模版文件中去定义一个变量,可以使用{assgin}标签:

{assign name='var' value='123'}     //也支持变量value='$name' 
{$var}

????????有变量的定义就会有常量的定义,可以使用{define}标签:

{define name='PI' value='3.1415'} 
{$Think.const.PI}

????????有时,实在不知道在模版中怎么进行编码时,可以采用{php}标签进行原生编码:

{php}
    echo '原生编码防止脱发'; 
{/php}

????????要注意的是:原生编码就是PHP编码,不能再使用模版引擎的特殊编码方式,比如{eq},{$user.name}这些标签语法均不支持。标签之间,是支持嵌套功能的,比如从列表中找到“樱桃小丸子”:

{foreach $list as $key=>$obj}
    {eq name='obj->username' value='樱桃小丸子'}
        ... 
    {/eq}
{/foreach}

模版的条件判断标签

switch标签

????????使用{switch}...{/switch}可以实现多个条件判断:

{switch number} 
    {case 1}1{/case} 
    {case 5}5{/case} 
    {case 10}10{/case} 
    {default/}不存在
{/switch}

????????{case}也支持多个条件判断,使用|线隔开即可:

{case 10|20|30}10,20,30均可{/case}

????????{case}后面也可以是变量,设置变量后不可以使用|线

{case $id}

IF标签

????????使用简单条件判断的{if}标签:

{if $number > 10}大于10{/if}

????????{if}标签的条件判断可以使用 ?AND、OR等语法:

{if ($number > 10) OR ($number > 5)}大于10{/if}

????????{if}标签支持{else/}语法:

{if $number > 10} 
    大于10
{else/} 
    小于10
{/if}

????????{if}标签也支持{elseif}多重条件判断:

{if $number > 100} 
    大于100
{elseif $number > 50}
    大于50 
{else}
    小于50 
{/if}

????????{if}标签中的条件判断支持 ?PHP写法,比如函数和对象调用:

{if strtoupper($user->name) == 'MR.LEE'} 
    确认李先生
{/if}

范围标签

????????范围标签:{in}和{notin},判断值是否存在或不存在指定的数据列表中:

{in name='number' value='10,20,30,40,50'}存在{/in} 
{in name='number' value='10,20,30,40,50'}
    存在数据列表中 
{else/}
    不存在数据列表中 
{/in}

????????name值可以是是系统变量,比如$Think.xxx.yyy,value可以是变量。范围标签:{between}和{notbetween},判断值是否存在或不存在数据区间中:

{between name='number' value='10,50'}存在{/between} 
{between name='number' value='10,50'}
    存在数据区间中 
{else/}
    不存在数据区间中 
{/between}

????????between中的 ?value只能是两个值,表示一个区间,第三个值会无效。区间不但可以表达数字,也可以是字母,比如 ?a-z,A-Z。

是否存在标签

????????是否存在:{present}和{notpresent}判断变量是否已经定义赋值(是否存在):

{present name='user'}存在{/present} 
{present name='user'}
    user已存在 
{else/}
    user不存在 
{/present}

????????是否为空:{empty}和{notempty}判断变量是否为空值:

{empty name='username'}有值{/empty} 
{empty name='username'}
username有值
{else/} 
    username没值
{/empty}

????????常量是否定义:{defined}和{notdefined}判断常量是否定义(是否存在):

{defined name='PI'} 
    PI存在
{else/}
    PI不存在 
{/defined}

模版的加载包含输出

包含文件

????????使用{include}标签来加载公用重复的文件,比如头部、尾部和导航部分。在模版 ?view目录创建一个public公共目录,分别创建header、footer和nav。然后创建 ?Block控制器,引入控制器模版 ?index,这个模版包含三个公用文件:

{include file='public/header,public/nav'/}

????????也可以包含一个文件的完整路径,包括后缀,如下:

{include file="../view/public/nav.html"/}

????????模版的标题和关键字,可以通过固定的语法进行传递。对于标题,在控制器先设置一下标题变量,然后设置{include}设置属性:

{include file='public/header'
    title='$title' keywords='关键字'/}

????????切换到public/header.html模版页面,使用[xxx]的方式调用数据:

<title>[title]</title>
<meta name="keywords" content="[keywords]" />

输出替换

????????有时,我们需要调用一些静态文件,比如 ?css/js等,直接写完整路径比较繁长,可以把这些路径整理打包。在目前二级目录下,view.php中,配置新增一个参数:

// 模版替换输出
'tpl_replace_string' => [
    '__JS__' => '../static/js', 
    '__CSS__' => '../static/css',
]

????????html文件调用端,直接通过__CSS__(__JS__)配置的魔术方法调用即可:

<link rel="stylesheet" type="text/css" href="__CSS__/basic.css"> 
<script type="text/javascript" src="__JS__/basic.js"></script>

????????在测试的时候,由于是更改的配置文件刷新,每次都要删除编译文件才能生效。

文件加载

????????传统方式调用 ?CSS或 ?JS文件时,采用link和script标签实现。系统提供了更加智能的加载方式,方便加载CSS和JS等文件;使用{load}标签和href属性来链接,不需要设置任何其它参数:

{load href='__CSS__/basic.css'/} 
{load href='__JS__/basic.js'/}

????????也支持 ?href多属性值的写法,如下:

{load href='__CSS__/basic.css, __JS__/basic.js'}

????????{load}还提供了两个别名{js}、{css}来更好的实现可读性:

{js href='__JS__/basic.js'} 
{css href='__CSS__/basic.css'}

????????{js}和{css}只是别名而已,识别.js还是.css是根据后缀的。

模版的布局和继承

模版布局

????????默认情况下,不支持模版布局功能,需要在配置文件中开启。在配置文件view.php中,配置开始模版布局功能:

'layout_on'    => true,

????????此时,执行上一节课的模版控制器,会发现提示缺少模版layout.html,这个默认的布局文件,是可以更改的,位置和名字均可配置:

'layout_name'  => 'public/layout',

????????layout.html负责所有通用模块的代码部分,而局部内容通过变量引入。使用{__CONTENT__}类似魔术方法的标签来引入index.html非通用内容:

{include file='public/header,public/nav' title='$title' keywords='关键字!'/}
{__CONTENT__}

????????你可以更改{__CONTENT__},只要在配置文件中配置:

'layout_item'  => '{__REPLACE__}'

? ? ? ? 再强调:再测试的时候,如果更改了配置文件,务必删除temp下编译文件再刷新。上面说的是第一种,配置文件下来开启布局,而第二种方式则不需要开启直接使用。首先,你必须关闭第一种配置,我这里就直接注释掉了,然后使用{layout}标签,只要在block.html的最上面加上如下代码,即可实现模版布局:

{layout name="public/layout" replace='[__REPLACE__]'}

?模版继承

????????模版继承是另一种布局方式,这种布局的思路更加的灵活。首先,我们要创建一个 ?public/base.html的基模版文件,文件名随意:

<!DOCTYPE html>
<html lang="en"> 
<head>
    <meta charset="UTF-8"> 
    <title>{$title}</title>
</head> 
<body>
</body> 
</html>

????????创建一个新的方法extend载入新的模版extend.html,然后加载基模版:

{extend name='public/base'}
{extend name='../view/public/base.html'}

????????在基模版 ?base.html中,设置几个可替换的区块部分,{block}标签实现:

{block name='nav'}nav{/block}
{block name='nav'}{include file='public/nav'}{/block} 
{block name='footer'} @ThinkPHP 版权所有 {/block}

????????在 ?base.html中,{include}可以加载内容,而在extend.html可以改变加载:

{block name='include'}{include file='public/header'}{/block}

模版的杂项和表单令牌

模版的杂项

????????有时,我们需要输出类似模版标签或语法的数据,这时会被模版解析,此时我们就使用模版的原样输出标签{literal}:

{literal}
变量标签形式:{$name} 
{/literal}

????????对于在 ?HTML页面中的标签,用 ?HTML注释是无效的,需要模版定义的注释:

{//$name} 
{/*$name*/} 
{/*
    多行注释 
*/}

????????注释和{符号之间不能有空格,否则无法实现注释隐藏;生成编译文件后,注释的内容会自动被删除,不会显示。

表单令牌

????????表单令牌就是在表单中增加一个隐藏字段,随机生成一串字符,确定不是伪造。这种随机产生的字符和服务器的 ?session(开启)进行对比,通过则是合法表单。

<form action="http://localhost/tp6/public/verify/token" method="post"> 
    <input type="hidden" name="__token__" value="{:token()}">
    <input type="submit" value="提交表单"> 
</form>

????????为了验证系统内部的机制,可以通过打印测试出内部的构造:

//打印出保存到session的token 
echo Session::get('__token__');

????????在验证端口,可以使用控制器验证单独验证 ?token是否验证成功:

$check = Request::checkToken('__token__');
if(false === $check) {
    throw new ValidateException('令牌错误'); 
}

????????验证器部分,只要使用内置规则 ?token即可验证,具体流程如下:

$validate = \think\facade\Validate::rule([
    'name'     =>     'require|token' 
]);

$result = $validate->batch(true)->check([
    'name'     =>     input('post.name'),
    '__token__' =>     input('post.__token__') ]);

if (!$result) {
    dump($validate->getError()); 
}

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 07:27:14  更:2021-07-28 07:28:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:52:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码