thinkphp笔记-模板杂项与表单令牌、session、cookie
模版的杂项
有时,我们需要输出类似模版标签或语法的数据,这时会被模版解析;就是{}会被模板解析,当要直接输出{}字符串的时候
此时,我们就使用模版的原样输出标签{literal};
{literal}
变量标签形式:{$name}
{/literal}
对于在HTML 页面中的标签,用HTML 注释是无效的,需要模版定义的注释;
{//$name}
{/*$name*/}
{/*
多行注释
*/}
注释和{符号之间不能有空格,否则无法实现注释隐藏;生成编译文件后,注释的内容会自动被删除,不会显示;
表单令牌
表单令牌就是在表单中增加一个隐藏字段,随机生成一串字符,确定不是伪造;
这种随机产生的字符和服务器的session(开启)进行对比,通过则是合法表单;
<form action="http://localhost/xuexi/tp6/public/verify/token" method="post">
<input type="text" name="__token__" value="{:token()}" size="40">
<input type="submit" value="提交验证">
</form>
需要开启session,在app/middleware.php中,开启session,不开的化会报错
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化 解开这个注释
\think\middleware\SessionInit::class
];
为了验证系统内部的机制,可以通过打印测试出内部的构造;
在controller/Verify.php中
public function token()
{
// 服务器生成的
echo session('__token__');
echo '<br>';
// 从模板提交过来的
echo input('post.__token__');
}
session('__token__') 相当于 Session::get('__token__');
可以发现如果直接点击提交,那么传递过来的与session中的token是一样的。
所以其机制就是只要提交过来的与session中的token对比,相等的话就是我自己的表单。
在验证端口,可以使用控制器验证单独验证token 是否验证成功;
public function token()
{
// 服务器生成的
echo session('__token__');
echo '<br>';
// 从模板提交过来的
echo input('post.__token__');
// 这个最终结果就是服务器session中token与表单提交的的'post.__token__'比较的结果
$check = Request()->checkToken('__token__');
if($check === false) {
echo '令牌无效';
}
}
由于input中输出了value="{:token()}",所以在Input中额外输入个字符就会在提交后触发“令牌无效”
// tp6.1.4中使用下面的调用方式会提示没有这个静态方法
// 这个可能是引入错误,应该引入门面模式的Request
use think\facade\Request;
// Non-static method think\Request::checkToken() should not be called staticall
$check = Request::checkToken('__token__');
第二种,使用验证器进行验证。只要使用内置规则token 即可验证,具体流程如下:
这种情况适用于,表单有很多数据,那么直接将token绑定一个数据一起传过来就行。
use think\facade\Validate;
$validate = Validate::rule([
// 验证name不能为空,且还要附带验证令牌
'name' => 'require|token',
]);
$result = $validate->batch(true)->check([
// 验证输入过来的name数据
'name' => input('post.name'),
// 必须要传入__token__数据,否则就会验证失败
'__token__' => input('post.__token__')
]);
if (!$result) {
dump($validate->getError());
}
session
在使用Session 之前,需要开启初始化,在全局中间件文件app/middleware.php;
// Session 初始化
\think\middleware\SessionInit::class
TP6.0 不支持原生$_SESSION 的获取方式,也不支持session_开头的函数;
直接使用::set()和::get()方法去设置Session 的存取;在控制器中
namespace app\controller;
use think\facade\Session;
class Store
{
public function session()
{
Session::set('user', 'wu');
return Session::get('user');
}
}
注意,一定要use usethink\facade\Session 门面模式的Session,这样才能静态调用set等方法!而不是 use think\Session;一定要注意!
Session::set('user', 'Mr.Lee'); //设置session,参数1 名称,参数2 值
Session::get('user'); //读取session,参数为名称
Session::all() //读取session 所有内容
Request::session('user'); //读取session,参数为名称
Request::session(); //读取session 所有内容
使用Request::静态方法的时候,注意要引入门面模式
namespace app\controller;
use think\facade\Request;
use think\facade\Session;
class Store
{
public function session()
{
Session::set('user', 'wu');
Session::set('count', 10);
// 获取某一个
dump(Request::session('user'));
// 啥都不传入 获取所有 等同 Session::all()
dump(Request::session());
}
}
::get()第二参数,可以设置当不存在值的时候,设置(返回)一个默认值;
dump( Session::get('name', 'default') );
Session::get('name') //name 不存在时返回null
Session::get('name', '') //name 不存在时返回空
::has()判断是否赋值,::delete()删除,::pull()取值后删除;
Session::has('name') // 判断session中是否有name属性 存在返回true
// 从session中删除user属性
Session::delete('user');
//pull是 get 和 delete双重功能
echo Session::pull('user');
echo '<br>';
return Session::get('user') . '1';
最后一行返回的一定是1,因为在第一个pull的时候输出后就删除掉user属性了。
::clear()清空整个session;
Session::clear();
::flash()方法,设置闪存数据,只请求一次有效的情况,再请求会失效;
// 这个值只能被取一次 取过之后就自动消失了
Session::flash('value', 100);
二维和助手函数
二维操作,就是对象和数组的调用方式,如下:
// 赋值(当前作用域)
Session::set('obj.user','Mr.Lee');
// 判断(当前作用域)是否赋值
Session::has('obj.user');
// 取值(当前作用域)
Session::get('obj.user');
// 删除(当前作用域)
Session::delete('obj.user');
助手函数,更加方便操作,如下
//赋值
session('user', 'Mr.Wu');
//has 判断
session('?user');
//delete 删除
session('user', null);
//清理全部
session(null);
//输出
echo session('user');
cookie
Cookie 是客户端存储,默认情况下是开启初始化的,在config/cookie.php;
::set()方法,创建一个最基本的cookie,可以设置前缀、过期时间、数组等;
Cookie::set('user', 'Mr.Lee'); //临时保存,关闭浏览器消失
Cookie::set('user', 'Mr.Lee', 3600); //3600 秒
Request::cookie('user');
Request::cookie(); // 获取全部的cookie
引入要引入门面模式
use think\facade\Cookie;
use think\facade\Request;
::forever()方法,永久保存Cookie(就是十年的意思);
Cookie::forever('user', 'Mr.Lee');
::has()判断是否存在,:get()取值,::delete()删除cookie;
Cookie::has('user');
Cookie::get('user');
Cookie::delete('user');
Cookie::get('user');与session是一样的,第二个参数指定一个当取不到的时候的默认值
Cookie::get('user', 1);
助手函数
助手函数,更加方便操作,如下:
cookie生效会慢半拍,不是即时生效的
echo cookie('user'); //输出
cookie('user', 'Mr.Lee', 3600); //设置
cookie('user', null); //删除
缓存功能
缓存主要是服务器数据库中数据长时间没有改变,则将数据存入缓存中,以提高数据读取速度。
系统内置了很多类型的缓存,除了File(默认),其它均需要结合相关产品;
配置文件app/config/cache.php 进行缓存配置,默认生成在runtime/cache 目录;
// 写入缓存
Cache::set('user', 'wu');
// 输出缓存中的数据
dump(Cache::get('user'));
一样使用门面模式引入
use think\facade\Cache;
::set()方法,可以设置一个缓存,参数3600毫秒为过期时间;
Cache::set('user', 'wu', 3600);
::has()方法,判断缓存是否存在,返回布尔值;
Cache::has('user');
::get()方法,从缓存中获取到相应的数据,无数据返回null;
Cache::get('user');
::inc()和::dec()实现缓存数据的自增和自减操作;
Cache::inc('num'); // 默认是1,通过不断的刷新,每次会自增1,实现计数功能
Cache::inc('price', 3); // 第二个参数是步长,每次刷新都会+3而不是+1
Cache::dec('num');
Cache::dec('price', 3);
::push()实现缓存的数组数据追加的功能;
Cache::set('arr', [1,2,3]);
Cache::push('arr', 4);
dump(Cache::get('arr')); 【1,2,3,4】
::delete()方法,可以删除指定的缓存文件;
Cache::set('user', 'wu', 3600);
Cache::delete('user');
dump(Cache::get('user')); // null
::pull()方法,先获取缓存值,然后再删除掉这个缓存,无数据返回null;
Cache::pull('user');
::remember()方法,如果数据不存在,则写入数据,可以依赖注入;
Cache::remember('start_time', time());
Cache::remember('start_time', function (Request $request) {})
具有set功能,写进去并立刻返回。
::clear()方法,可以清除所有缓存;
Cache::clear();
::tag()标签,可以将多个缓存归类到标签中,方便统一管理,比如清除;
Cache::tag('tag')->set('age', 100);
Cache::tag('tag')->clear();
dump(Cache::get('age'));
上面这个例子是先新建一个标签,名叫tag,然后在标签中新建缓存数据age=100,然后清空的时候,只清空tag标签中的数据,这样就可以保护其他的缓存数据步受影响。
助手函数的使用:cache();
//设置缓存
cache('user', 'Mr.Lee', 3600);
//输出缓存
echo cache('user');
//删除指定缓存
cache('user', null);