thinkphp-请求对象get和信息、请求变量、伪静态、参数绑定、请求缓存
请求对象和信息
https://kancloud.cn/manual/thinkphp6_0/1037518
请求对象
比如在浏览器的URL中,输入一个值,那么如何获取这个值就是用请求。
例如我们访问这个链接:http://localhost/xuexi/tp6/public/rely?username=555,如果要获取其中?查询字符串的参数
在controller/Rely.php中,使用依赖注入,获取查询字符串的参数:
namespace app\controller;
use app\Request;
class Rely
{
public function index(Request $request)
{
return $request->param('username');
}
}
上面方法有个明显缺点,就是每个方法都要调用一次Request $request,不如直接在构造方法里保存。
例如访问 http://localhost/xuexi/tp6/public/rely/get?username=555
namespace app\controller;
use app\Request;
class Rely
{
protected $request;
public function __construct(Request $request)
{
$this->request = $request;
}
public function get()
{
return $this->request->param('username');
}
使用Facade 方式应用于没有进行依赖注入时使用Request 对象的场合
public function get()
{
// return $this->request->param('username');
return \think\facade\Request::param('username');
}
或者在文件里面先use一下(推荐这种方法)
namespace app\controller;
use think\facade\Request;
class Rely
{
public function get()
{
return Request::param('username');
}
}
注意use think\facade\Request; 与use app\Request; 是冲突的,二者只能选其一
使用助手函数request()方法也可以应用在没有依赖注入的场合;
public function get()
{
return request()->param('username');
}
直接使用,什么饮用都不需要。一般推荐后面两种。
请求信息
Request 对象除了param 方法外,还有一些请求的固定信息,如表
方法 | 含义 |
---|---|
host | 当前访问域名或者IP |
scheme | 当前访问协议 |
port | 当前访问的端口 |
remotePort | 当前请求的REMOTE_PORT |
protocol | 当前请求的SERVER_PROTOCOL |
contentType | 当前请求的CONTENT_TYPE |
domain | 当前包含协议的域名 |
subDomain | 当前访问的子域名 |
panDomain | 当前访问的泛域名 |
rootDomain | 当前访问的根域名 |
url | 当前完整URL |
baseUrl | 当前URL(不含QUERY_STRING) |
query | 当前请求的QUERY_STRING参数 |
baseFile | 当前执行的文件 |
root | URL访问根地址 |
rootUrl | URL访问根目录 |
pathinfo | 当前请求URL的pathinfo信息(含URL后缀) |
ext | 当前URL的访问后缀 |
time | 获取当前请求的时间 |
type | 当前请求的资源类型 |
method | 当前请求类型 |
rule | 当前请求的路由对象实例 |
上表的调用方法,直接调用即可,无须传入值,只有极个别如果传入true 获取完整URL 的功能;
Request::url(); // /xuexi/tp6/public/rely/get?username=555
// 获取完整URL 地址包含域名 http://localhost/xuexi/tp6/public/rely/get?username=555
Request::url(true);
// 获取当前URL(不含QUERY_STRING) 不带域名
Request::baseFile();
// 获取当前URL(不含QUERY_STRING) 包含域名
Request::baseFile(true);
// 获取URL 访问根地址不带域名
Request::root();
// 获取URL 访问根地址包含域名
Request::root(true);
还可以获取当前控制器和操作方法的名称:::controller()和::action();
return Request::controller() . '|' . Request::action();
请求变量
https://www.kancloud.cn/manual/thinkphp6_0/1037519
Request 对象支持全局变量的检测、获取和安全过滤,支持$_GET、$_POST...等;
为了方便演示,这里一律使用Facade 的静态调用模式;
使用has()方法,可以检测全局变量是否已经设置:
namespace app\controller;
use think\facade\Request;
class Rely
{
public function get()
{
dump(Request::has('id'));
dump(Request::has('id', 'get')); // 检测是get方式不存在还是post方式不存在
}
}
Request::has('id', 'get');
Request::has('username', 'post');
Request 支持的所有变量类型方法,如下表:
方法 | 描述 |
---|---|
param | 获取当前请求的变量(推荐) |
get | 获取 $_GET 变量 |
post | 获取 $_POST 变量 |
put | 获取 PUT 变量 |
delete | 获取 DELETE 变量 |
session | 获取 SESSION 变量 |
cookie | 获取 $_COOKIE 变量 |
request | 获取 $_REQUEST 变量 |
server | 获取 $_SERVER 变量 |
env | 获取 $_ENV 变量 |
route | 获取 路由(包括PATHINFO) 变量 |
middleware | 获取 中间件赋值/传递的变量 |
file | 获取 $_FILES 变量 |
allV6.0.8+ | 获取包括 $_FILES 变量在内的请求变量,相当于param+file |
param()变量方法是自动识别GET、POST 等的当前请求,推荐使用;
比如这个链接:http://localhost/xuexi/tp6/public/rely/get?name=555&user=wu&age=15
//获取请求为name 的值,过滤
Request::param('name');
//获取所有请求的变量,以数组形式,过滤
Request::param();
//获取所有请求的变量(原始变量),不包含上传变量,不过滤
Request::param(false);
//获取部分变量 只获取name和age的值
Request::param(['name','age']);
默认情况下,并没有配置字符过滤器,可在app\Request.php 这是一个空的应用请求对象类 配置;
namespace app;
// 应用请求对象类
class Request extends \think\Request
{
protected $filter = ['htmlspecialchars']; \\ 加上这句
}
加上之后,就会对html字符串标签进行转义。
如果没有设置字符过滤器,或者局部用别的字符过滤器,可以通过第三参数
dump(Request::param('name', '', 'strtoupper'));
第二个参数是default默认值,这里设置为空,第三个参数是过滤器
例如链接:tp6/public/rely/get?name=work<>&user=wu&age=15
这里会返回"WORK<>",发现过滤器会失效,如果要支持多个过滤效果:
添加过滤后,字符串处理结果如下:^"WORK<>" 支持写多个过滤效果。
dump(Request::param('name', '', 'strtoupper,htmlspecialchars')); // 注意第三个参数逗号,左右不能有空格!
Request::param('name', '', 'htmlspecialchars');
Request::param('name', '', 'strip_tags,strtolower');
如果设置了全局字符过滤器,但又不想某个局部使用,可以只用null 参数
dump(Request::param(['name', 'age'], '', null));
"name" => "work<>"
"age" => "15"
如果获取不到值,支持请求的变量设置一个默认值,即第二个参数
Request::param('name', '默认值');
如果采用的是路由URL,也可以获取到变量,但param::get()不支持路由变量
先在route/app.php中配置一个路由,访问地址:http://localhost/xuexi/tp6/public/re/5?id=6
Route::rule('/re/:id', 'Rely/get');
// 只能获取?id=6
dump(Request::get('id'));
// 只能获取路由中的:id
dump(Request::route('id'));
注意情况的区分。
dump(Request::param('id'));
// 当get和路由方式都存在的时候,会优先获取路由的id,这里结果是5
使用only()方法,可以获取指定的变量,也可以设置默认值;
http://localhost/xuexi/tp6/public/re/5?id=6&name=wu
Request::only(['id','name']); // 6, wu
Request::only(['id'=>1,'name'=>'默认值']);
相反的except()方法,就是排除指定的变量;除了指定的,其余的都获取。指向符号=>就是默认值
Request::except('id,name');
Request::except(['id','name']);
Request::except(['id'=>1,'name'=>'默认值']);
Request::except(['id','name'], 'post');
使用变量修饰符,可以将参数强制转换成指定的类型;
/s(字符串)、/d(整型)、/b(布尔)、/a(数组)、/f(浮点);
// 强制转换为数字
dump(Request::param('id/d'));
助手函数
为了简化操作,Request 对象提供了助手函数;
input('?get.id'); //判断get 下的id 是否存在
input('?post.name'); //判断post 下的name 是否存在
input('param.name'); //获取param 下的name 值
input('param.name', '默认值'); //默认值
input('param.name', '', 'htmlspecialchars'); //过滤器
input('param.id/d'); //设置强制转换
/tp6/public/re/5?id=abc&name=wu
dump(input('?get.id')); // 判断?后面的id是否存在
dump(input('get.id')); // 获取?id的值
dump(input('param.id')); // 等同于get.id
伪静态、参数绑定、请求缓存
伪静态
可以通过config/route.php 修改伪静态的后缀,比如修改成shtml、xml 等;
'url_html_suffix' => 'html|xml', // false则是关闭伪静态
如果地址栏用后缀访问成功后,可以使用Request::ext()方法得到当前伪静态;
echo Request::ext(); // 返回html
配置文件伪静态后缀,可以支持多个,用竖线隔开
'url_html_suffix' => 'shtml|xml|pdf'
直接将伪静态配置文件设置为false,则关闭伪静态功能;
'url_html_suffix' => false
参数绑定
参数绑定功能:即URL 地址栏的数据传参,我们一直在使用的功能;
public function get($id, $name)
{
return 'get:'.$id . $name;
}
不管是:/id/5/name/lee,还是:/name/lee/id/5,都不会产生错误
为避免错误,可以给id和name参数设置默认值。
请求缓存
请求缓存仅对GET 请求有效,可以在全局和局部设置缓存;
同一个地址,如果内容没有更改,那么在第二次请求的时候,会发一个304的状态码,那么代表就是要读取缓存的内容了。
首先、如果要设置全局请求缓存,在中间件文件app/middleware.php 中设置;
// 全局中间件定义文件
return [
// 全局请求缓存
\think\middleware\CheckRequestCache::class,
或者 'think\middleware\CheckRequestCache',
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
// \think\middleware\SessionInit::class
];
其次、在config/route.php 中设置缓存的声明周期即可 (默认是Null)
'request_cache_expire' => 3600,
如果仅仅针对某个路由进行缓存:
1-首先关闭掉全局缓存
2-有效期设置为Null
// 请求缓存有效期
'request_cache_expire' => null,
3-在route/app.php中
Route::rule('/re/:id', 'Rely/get')->cache(3600);
而如果全局缓存处于开启状态,但是某一条路由不需要全局缓存,那么:
Route::rule('/re/:id', 'Rely/get')->cache(false);