10.thinkphp的响应
响应输出
响应操作
1. 响应输出,有好几种:包括return、json()和view()等等;
2. 默认输出方式是以html格式输出,如果你发起json请求,则输出json;
3. 而背后是response对象,可以用response()输出达到相同的效果;
return response($data);
4. 使用response()方法可以设置第二参数,状态码,或调用code()方法;
return response($data, 201);return response($data)->code(202);
5. 使用json()、view()方法和response()返回的数据类型不同,效果一样;
return json($data, 201);
return json($data)->code(202);
6. 不但可以设置状态码,还可以设置header()头文件信息;
return json($data)->code(202)->
header(['Cache-control' => 'no-cache,must-revalidate']);
============================================================
大多数情况,我们不需要关注Response
对象本身,只需要在控制器的操作方法中返回数据即可。
最简单的响应输出是直接在路由闭包或者控制器操作方法中返回一个字符串,例如:
Route::get('hello/:name', function ($name) {return 'Hello,' . $name . '!';
});
<?php
namespace app\controller;class Index
{public function hello($name='thinkphp'){return 'Hello,' . $name . '!';}
}
由于默认是输出Html
输出,所以直接以html页面方式输出响应内容。如果你发起一个JSON请求的话,输出就会自动使用JSON格式响应输出。
为了规范和清晰起见,最佳的方式是在控制器最后明确输出类型(毕竟一个确定的请求是有明确的响应输出类型),默认支持的输出类型包括:
输出类型 | 快捷方法 | 对应Response类 |
---|---|---|
HTML输出 | response | \think\Response |
渲染模板输出 | view | \think\response\View |
JSON输出 | json | \think\response\Json |
JSONP输出 | jsonp | \think\response\Jsonp |
XML输出 | xml | \think\response\Xml |
页面重定向 | redirect | \think\response\Redirect |
附件下载 | download | \think\response\File |
每一种输出类型其实对应了一个不同的Response
子类(response()
函数对应的是Response
基类),也可以在应用中自定义Response
子类满足特殊需求的输出。
例如我们需要输出一个JSON数据给客户端(或者AJAX请求),可以使用:
<?php
namespace app\controller;class Index
{public function hello(){$data = ['name' => 'thinkphp', 'status' => '1'];return json($data);}
}
这些助手函数的返回值都是Response
类或者子类的对象实例,所以后续可以调用Response
基类或者当前子类的相关方法,后面我们会讲解相关方法。
如果你只需要输出一个html格式的内容,可以直接使用
<?php
namespace app\controller;class Index
{public function hello(){$data = 'Hello,ThinkPHP!';return response($data);}
}
或者使用return
直接返回输出的字符串。
<?php
namespace app\controller;class Index
{public function hello(){return 'Hello,ThinkPHP!';}
}
Response
对象提供了一系列方法用于设置响应参数,包括设置输出内容、状态码及header
信息等,并且支持链式调用以及多次调用。
设置数据
Response
基类提供了data
方法用于设置响应数据。
response()->data($data);
json()->data($data);
不过需要注意的是data
方法设置的只是原始数据,并不一定是最终的输出数据,最终的响应输出数据是会根据当前的Response
响应类型做自动转换的,例如:
json()->data($data);
最终的输出数据就是json_encode($data)
转换后的数据。
如果要获取当前响应对象实例的实际输出数据可以使用getContent
方法。
设置状态码
Response
基类提供了code
方法用于设置响应数据,但大部分情况一般我们是直接在调用助手函数的时候直接传入状态码,例如:
json($data,201);
view($data,401);
或者在后面链式调用code
方法是等效的:
json($data)->code(201);
除了redirect
函数的默认返回状态码是302
之外,其它方法没有指定状态码都是返回200
状态码。
如果要获取当前响应对象实例的状态码的值,可以使用getCode
方法。
设置头信息
可以使用Response
类的header
设置响应的头信息
json($data)->code(201)->header(['Cache-control' => 'no-cache,must-revalidate'
]);
除了header
方法之外,Response
基类还提供了常用头信息的快捷设置方法:
方法名 | 作用 |
---|---|
lastModified | 设置Last-Modified 头信息 |
expires | 设置Expires 头信息 |
eTag | 设置ETag 头信息 |
cacheControl | 设置Cache-control 头信息 |
contentType | 设置Content-Type 头信息 |
除非你要清楚自己在做什么,否则不要随便更改这些头信息,每个Response
子类都有默认的contentType
信息,一般无需设置。
你可以使用getHeader
方法获取当前响应对象实例的头信息。
写入Cookie
response()->cookie('name', 'value', 600);
设置额外参数
有些时候,响应输出需要设置一些额外的参数,例如:
在进行json
输出的时候需要设置json_encode
方法的额外参数,jsonp
输出的时候需要设置jsonp_handler
等参数,这些都可以使用options
方法来进行处理,例如:
jsonp($data)->options(['var_jsonp_handler' => 'callback','default_jsonp_handler' => 'jsonpReturn','json_encode_param' => JSON_PRETTY_PRINT,
]);
关闭当前的请求缓存
支持使用allowCache
方法动态控制是否需要使用请求缓存。
// 关闭当前页面的请求缓存
json($data)->code(201)->allowCache(false);
自定义响应
如果需要特别的自定义响应输出,可以自定义一个Response
子类,并且在控制器的操作方法中直接返回。又或者通过设置响应参数的方式进行响应设置输出。
===============================================================
1. 使用redirect()方法可以实现页面重定向,需要return执行;
return redirect('http://www.baidu.com');
2. 站内重定向,直接输入路由地址或相对地址即可,第二参数状态码;
return redirect('ds/5');return redirect('/address/details/id/5', 201);
3. 使用url自动生成跳转地址,普通地址或路由地址;
return redirect(url('address/index'));
4. 附加session信息,并跳转重定向;
return redirect(url('address/index'))->with('name', 'Mr.Lee');
5. 重定向还提供了,记住上一次的url,和跳转到上一次url的功能;
if (session('?flag')) {return '死机警告';} else {return redirect(url('address/index'))->remember();}public function index(){$url = url('address/back');return '<a href="'.$url.'">返回<a>';}public function back(){return redirect('1')->with('flag', '1')->restore();
}
=======================================================
重定向
可以使用redirect
助手函数进行重定向
<?php
namespace app\controller;class Index
{public function hello(){return redirect('http://www.thinkphp.cn');}
}
重定向传参
如果是站内重定向的话,可以支持URL组装,有两种方式组装URL,第一种是直接使用完整地址(/
打头)
redirect('/index/hello/name/thinkphp');
如果你需要自动生成URL地址,应该在调用之前调用url函数先生成最终的URL地址。
redirect((string) url('hello',['name' => 'think']));
还可以支持使用with
方法附加Session
闪存数据重定向。
<?php
namespace app\controller;class Index
{public function index(){return redirect('/hello')->with('name','thinkphp');}public function hello(){$name = session('name');return 'hello,'.$name.'!';}
}
从示例可以看到重定向隐式传值使用的是Session
闪存数据隐式传值,并且仅在下一次请求有效,再次访问重定向地址的时候无效。
记住请求地址
在很多时候,我们重定向的时候需要记住当前请求地址(为了便于跳转回来),我们可以使用remember
方法记住重定向之前的请求地址。
下面是一个示例,我们第一次访问index
操作的时候会重定向到hello
操作并记住当前请求地址,然后操作完成后到restore
方法,restore
方法则会自动重定向到之前记住的请求地址,完成一次重定向的回归,回到原点!(再次刷新页面又可以继续执行)
<?php
namespace app\controller;class Index
{public function index(){// 判断session完成标记是否存在if (session('?complete')) {// 删除sessionsession('complete', null);return '重定向完成,回到原点!';} else {// 记住当前地址并重定向return redirect('hello')->with('name', 'thinkphp')->remember();}}public function hello(){$name = session('name');return 'hello,' . $name . '! <br/><a href="/index/index/restore">点击回到来源地址</a>';}public function restore(){// 设置session标记完成session('complete', true);// 跳回之前的来源地址return redirect()->restore();}
}
文件下载
支持文件下载功能,可以更简单的读取文件进行下载操作,支持直接下载输出内容。
你可以在控制器的操作方法中添加如下代码:
public function download(){// download是系统封装的一个助手函数return download('image.jpg', 'my.jpg');}
访问download
操作就会下载命名为my.jpg
的图像文件。
下载文件的路径是服务器路径而不是URL路径,如果要下载的文件不存在,系统会抛出异常。
下载文件名可以省略后缀,会自动判断(后面的代码都以助手函数为例)
public function download(){// 和上面的下载文件名是一样的效果return download('image.jpg', 'my');}
如果需要设置文件下载的有效期,可以使用
public function download(){// 设置300秒有效期return download('image.jpg', 'my')->expire(300);}
除了expire
方法外,还支持下面的方法:
方法 | 描述 |
---|---|
name | 命名下载文件 |
expire | 下载有效期 |
isContent | 是否为内容下载 |
mimeType | 设置文件的mimeType类型 |
force | 是否强制下载(V6.0.3+ ) |
助手函数提供了内容下载的参数,如果需要直接下载内容,可以在第三个参数传入true
:
public function download()
{$data = '这是一个测试文件';return download($data, 'test.txt', true);
}
V6.0.3+
版本开始,支持设置是否强制下载,例如需要打开图像文件而不是浏览器下载的话,可以使用:
public function download()
{return download('image.jpg', 'my.jpg')->force(false);
}