HTTP 响应
Response 类扩展了 HTTP 消息类,其中包含仅适用于响应调用它的客户端的服务器的方法。
使用 Response
Response 类会为您实例化并传递到您的控制器中。可以通过 $this->response
访问它。它与 Services::response()
返回的实例相同。我们称之为全局响应实例。
很多时候您不需要直接接触该类,因为 CodeIgniter 会为您处理发送头信息和主体。如果页面成功创建了它被要求创建的内容,这很好。当出现问题时,或者您需要发送非常特定的状态码,甚至利用强大的 HTTP 缓存,它就在那里为您服务。
设置输出
当您需要直接设置脚本的输出,而不是依赖 CodeIgniter 自动获取它时,您可以使用 setBody
方法手动设置。这通常与设置响应的状态代码一起使用。
<?php
$this->response->setStatusCode(404)->setBody($body);
原因短语(“OK”、“Created”、“Moved Permanently”)将自动添加,但您可以在 setStatusCode()
方法的第二个参数中添加自定义原因。
<?php
$this->response->setStatusCode(404, 'Nope. Not here.');
您可以将数组格式化为 JSON 或 XML,并使用 setJSON()
和 setXML()
方法将内容类型标头设置为相应的 MIME 类型。通常,您将发送要转换的数据数组。
<?php
$data = [
'success' => true,
'id' => 123,
];
return $this->response->setJSON($data);
// or
return $this->response->setXML($data);
设置标头
setHeader()
通常,您需要为响应设置标头。Response 类使用 setHeader()
方法使这变得非常简单。
第一个参数是标头的名称。第二个参数是值,可以是字符串或值数组,这些值在发送到客户端时将被正确组合。
<?php
$this->response->setHeader('Location', 'http://example.com')
->setHeader('WWW-Authenticate', 'Negotiate');
使用这些函数而不是使用本机 PHP 函数可以确保不会过早发送标头,从而导致错误,并使测试成为可能。
注意
此方法仅将标头设置为响应实例。因此,如果您创建并返回另一个响应实例(例如,如果您调用 redirect()
),此处设置的标头将不会自动发送。
appendHeader()
如果标头存在并且可以具有多个值,您可以使用 appendHeader()
和 prependHeader()
方法将值分别添加到值列表的末尾或开头。第一个参数是标头的名称,第二个参数是要追加或预置的值。
<?php
$this->response->setHeader('Cache-Control', 'no-cache')
->appendHeader('Cache-Control', 'must-revalidate');
removeHeader()
可以使用 removeHeader()
方法从响应中删除标头,该方法仅将标头名称作为参数。这与大小写无关。
<?php
$this->response->removeHeader('Location');
重定向
如果您想创建重定向,请使用 redirect()
函数。
它返回一个 RedirectResponse
实例。它与 Services::response()
返回的全局响应实例不同。
警告
如果您在调用 redirect()
之前设置了 Cookie 或响应头,它们将被设置为全局响应实例,并且不会自动复制到 RedirectResponse
实例。要发送它们,您需要手动调用 withCookies()
或 withHeaders()
方法。
重要
如果您想重定向,则必须在 控制器 或 控制器过滤器 的方法中返回一个 RedirectResponse
实例。请注意,__construct()
或 initController()
方法不能返回任何值。如果您忘记返回 RedirectResponse
,则不会发生重定向。
重定向到 URI 路径
当您想传递一个 URI 路径(相对于 baseURL)时,请使用 redirect()->to()
// Go to specific URI path. "admin/home" is the URI path relative to baseURL.
return redirect()->to('admin/home');
注意
如果您的 URL 中有一个您想删除的片段,您可以在方法中使用 refresh 参数。例如 return redirect()->to('admin/home', null, 'refresh');
。
重定向到已定义的路由
当您想传递一个 路由名称 或 Controller::method 用于 反向路由 时,请使用 redirect()->route()
// Go to a named route. "user_gallery" is the route name, not a URI path.
return redirect()->route('user_gallery');
当将参数传递给函数时,它被视为反向路由的路由名称或 Controller::method,而不是相对/完整 URI,与使用 redirect()->route()
相同。
// Go to a named/reverse-routed URI.
return redirect('named_route');
重定向回
当您想重定向回时,请使用 redirect()->back()
// Go back to the previous page.
return redirect()->back();
// Keep the old input values upon redirect so they can be used by the `old()` function.
return redirect()->back()->withInput();
// Set a flash message.
return redirect()->back()->with('foo', 'message');
注意
redirect()->back()
与浏览器“后退”按钮不同。它将访问者带到“会话期间查看的最后一页”,当会话可用时。如果会话尚未加载或不可用,则将使用 HTTP_REFERER 的净化版本。
使用 Headers 重定向
如果您在调用 redirect()
之前设置了响应 Headers,它们将被设置为全局响应实例,并且不会自动复制到 RedirectResponse
实例中。
要发送 Headers,您需要手动调用 withHeaders()
方法。
// Copies all headers from the global response instance.
return redirect()->back()->withHeaders();
重定向状态码
GET 请求的默认 HTTP 状态码为 302。但是,在使用 HTTP/1.1 或更高版本时,303 用于 POST/PUT/DELETE 请求,307 用于所有其他请求。
您可以指定状态码
// Redirect to a URI path relative to baseURL with status code 301.
return redirect()->to('admin/home', 301);
// Redirect to a route with status code 308.
return redirect()->route('user_gallery', [], 308);
// Redirect back with status code 302.
return redirect()->back(302);
注意
由于一个 bug,在 v4.3.3 或更早版本中,即使指定了状态码,实际重定向响应的状态码也可能会被更改。请参阅 ChangeLog v4.3.4。
如果您不知道重定向的 HTTP 状态码,建议您阅读 HTTP 中的重定向。
强制文件下载
Response 类提供了一种简单的方法,可以将文件发送到客户端,提示浏览器将数据下载到您的计算机。这将设置适当的 Headers 以使其发生。
第一个参数是您希望下载的文件的名称,第二个参数是文件数据。
如果您将第二个参数设置为 null 并且 $filename
是一个现有的可读文件路径,那么它的内容将被读取。
如果您将第三个参数设置为布尔值 true,那么将发送实际的文件 MIME 类型(基于文件名扩展名),因此如果您的浏览器有该类型的处理程序,它可以使用它。
示例
<?php
$data = 'Here is some text!';
$name = 'mytext.txt';
return $this->response->download($name, $data);
如果您想从服务器下载现有文件,您需要为第二个参数显式传递 null
<?php
// Contents of photo.jpg will be automatically read
return $this->response->download('/path/to/photo.jpg', null);
使用可选的 setFileName()
方法更改发送到客户端浏览器时的文件名
<?php
return $this->response->download('awkwardEncryptedFileName.fakeExt', null)->setFileName('expenses.csv');
注意
必须返回响应对象才能将下载发送到客户端。这允许在将响应发送到客户端之前,将其通过所有 **after** 过滤器。
在浏览器中打开文件
一些浏览器可以显示 PDF 等文件。要告诉浏览器显示文件而不是保存它,请调用 DownloadResponse::inline()
方法。
<?php
$data = 'Here is some text!';
$name = 'mytext.txt';
return $this->response->download($name, $data)->inline();
HTTP 缓存
HTTP 规范内置了工具,可以帮助客户端(通常是 Web 浏览器)缓存结果。正确使用它可以极大地提高应用程序的性能,因为它会告诉客户端他们不需要联系服务器,因为没有任何变化。而且你不可能比这更快了。
这些通过 Cache-Control
和 ETag
标头处理。本指南不是对所有缓存标头功能进行全面介绍的合适地方,但您可以在 Google Developers 上获得很好的理解。
默认情况下,通过 CodeIgniter 发送的所有响应对象都关闭了 HTTP 缓存。选项和确切情况过于多样,我们无法创建除关闭之外的良好默认值。通过 setCache()
方法,您可以轻松地将缓存值设置为所需的值
<?php
$options = [
'max-age' => 300,
's-maxage' => 900,
'etag' => 'abcde',
];
$this->response->setCache($options);
$options
数组只接受键值对数组,除了少数例外,这些键值对被分配给 Cache-Control
标头。您可以根据自己的具体情况自由地设置所有选项。虽然大多数选项都应用于 Cache-Control
标头,但它会智能地处理 etag
和 last-modified
选项,并将它们分配到相应的标头。
类参考
注意
除了这里列出的方法之外,此类还继承了来自 消息类 的方法。
父类提供的可用方法是
CodeIgniter\HTTP\Message::body()
CodeIgniter\HTTP\Message::setBody()
CodeIgniter\HTTP\Message::populateHeaders()
CodeIgniter\HTTP\Message::headers()
CodeIgniter\HTTP\Message::header()
CodeIgniter\HTTP\Message::headerLine()
CodeIgniter\HTTP\Message::setHeader()
CodeIgniter\HTTP\Message::removeHeader()
CodeIgniter\HTTP\Message::appendHeader()
CodeIgniter\HTTP\Message::protocolVersion()
CodeIgniter\HTTP\Message::setProtocolVersion()
CodeIgniter\HTTP\Message::negotiateMedia()
CodeIgniter\HTTP\Message::negotiateCharset()
CodeIgniter\HTTP\Message::negotiateEncoding()
CodeIgniter\HTTP\Message::negotiateLanguage()
CodeIgniter\HTTP\Message::negotiateLanguage()
- class CodeIgniter\HTTP\Response
- getStatusCode()
- 返回:
此响应的当前 HTTP 状态代码
- 返回类型:
int
返回此响应的当前状态代码。如果未设置状态代码,则会抛出 BadMethodCallException
<?php echo $response->getStatusCode();
- setStatusCode($code[, $reason=''])
- 参数:
$code (
int
) – HTTP 状态代码$reason (
string
) – 可选的理由短语。
- 返回:
当前响应实例
- 返回类型:
CodeIgniter\HTTP\Response
设置应与此响应一起发送的 HTTP 状态代码
<?php $response->setStatusCode(404);
原因短语将根据官方列表自动生成。如果您需要为自定义状态代码设置自己的原因短语,可以将原因短语作为第二个参数传递。
<?php $response->setStatusCode(230, 'Tardis initiated');
- getReasonPhrase()
- 返回:
当前的原因短语。
- 返回类型:
string
返回此响应的当前状态代码。如果未设置状态,将返回空字符串。
<?php echo $response->getReasonPhrase();
- setDate($date)
- 参数:
$date (
DateTime
) – 用于设置此响应时间的 DateTime 实例。
- 返回:
当前的响应实例。
- 返回类型:
CodeIgniter\HTTP\Response
设置此响应使用的日期。
$date
参数必须是DateTime
的实例。
- setContentType($mime[, $charset='UTF-8'])
- 参数:
$mime (
string
) – 此响应代表的 MIME 类型。$charset (
string
) – 此响应使用的字符集。
- 返回:
当前的响应实例。
- 返回类型:
CodeIgniter\HTTP\Response
设置此响应代表的 MIME 类型。
<?php $response->setContentType('text/plain'); $response->setContentType('text/html'); $response->setContentType('application/json');
默认情况下,该方法将字符集设置为
UTF-8
。如果您需要更改此设置,可以将字符集作为第二个参数传递。<?php $response->setContentType('text/plain', 'x-pig-latin');
- noCache()
- 返回:
当前的响应实例。
- 返回类型:
CodeIgniter\HTTP\Response
将
Cache-Control
标头设置为关闭所有 HTTP 缓存。这是所有响应消息的默认设置。<?php $response->noCache(); /* * Sets the following header: * Cache-Control: no-store, max-age=0, no-cache */
- setCache($options)
- 参数:
$options (
array
) – 一组键值对的缓存控制设置
- 返回:
当前的响应实例。
- 返回类型:
CodeIgniter\HTTP\Response
设置
Cache-Control
头部,包括ETags
和Last-Modified
。常见的键包括:etag
last-modified
max-age
s-maxage
private
public
must-revalidate
proxy-revalidate
no-transform
当传递 last-modified 选项时,它可以是日期字符串或 DateTime 对象。
- setLastModified($date)
- 参数:
$date (
string|DateTime
) – 设置 Last-Modified 头部的日期
- 返回:
当前的响应实例。
- 返回类型:
CodeIgniter\HTTP\Response
设置
Last-Modified
头部。$date
对象可以是字符串或DateTime
实例。<?php $response->setLastModified(date('D, d M Y H:i:s')); $response->setLastModified(\DateTime::createFromFormat('!U', $timestamp));
- send() Response
- 返回:
当前的响应实例。
- 返回类型:
CodeIgniter\HTTP\Response
告诉响应将所有内容发送回客户端。这将首先发送头部,然后发送响应主体。对于主应用程序响应,您不需要调用此方法,因为它由 CodeIgniter 自动处理。
- setCookie($name = ''[, $value = ''[, $expire = ''[, $domain = ''[, $path = '/'[, $prefix = ''[, $secure = false[, $httponly = false[, $samesite = null]]]]]]])
- 参数:
$name (
array|Cookie|string
) – Cookie 名称 或 此方法所有可用参数的关联数组 或CodeIgniter\Cookie\Cookie
的实例$value (
string
) – Cookie 值$expire (
int
) – Cookie 过期时间,以秒为单位。如果设置为0
,则 cookie 仅在浏览器打开时有效$domain (
string
) – Cookie 域名$path (
string
) – Cookie 路径$prefix (
string
) – Cookie 名称前缀。如果设置为''
,将使用 **app/Config/Cookie.php** 中的默认值$secure (
bool
) – 是否仅通过 HTTPS 传输 cookie。如果设置为null
,将使用 **app/Config/Cookie.php** 中的默认值$httponly (
bool
) – 是否仅使 cookie 可用于 HTTP 请求(无 JavaScript)。如果设置为null
,将使用 **app/Config/Cookie.php** 中的默认值$samesite (
string
) – SameSite cookie 参数的值。如果设置为''
,则不会在 cookie 上设置 SameSite 属性。如果设置为null
,将使用 **app/Config/Cookie.php** 中的默认值
- 返回类型:
void
注意
在 v4.2.7 之前,由于一个 bug,
$secure
和$httponly
的默认值是false
,并且来自 app/Config/Cookie.php 的这些值从未被使用。在 Response 实例中设置一个包含您指定值的 cookie。
有两种方法可以将信息传递给此方法以设置 cookie:数组方法和离散参数
数组方法
使用此方法,关联数组作为第一个参数传递
<?php $cookie = [ 'name' => 'The Cookie Name', 'value' => 'The Value', 'expire' => '86500', 'domain' => '.some-domain.com', 'path' => '/', 'prefix' => 'myprefix_', 'secure' => true, 'httponly' => false, 'samesite' => 'Lax', ]; $response->setCookie($cookie);
只有
name
和value
是必需的。要删除 cookie,请将其设置为expire
为空。expire
以 **秒** 为单位设置,它将添加到当前时间。不要包含时间,而只包含您希望 cookie 有效的从现在开始的秒数。如果expire
设置为零,cookie 将只在浏览器打开时有效。注意
但是,如果
value
设置为空字符串,并且expire
设置为0
,则 cookie 将被删除。对于无论您的网站如何请求都适用的全站 cookie,请将您的 URL 添加到
domain
中,以句点开头,例如:.your-domain.compath
通常不需要,因为该方法设置了根路径。prefix
仅在您需要避免与服务器上其他同名 cookie 发生名称冲突时才需要。secure
标志仅在您希望将其设置为安全 cookie 时才需要,方法是将其设置为true
。samesite
值控制 cookie 如何在域和子域之间共享。允许的值为'None'
、'Lax'
、'Strict'
或空字符串''
。如果设置为空字符串,将设置默认的 SameSite 属性。离散参数
如果您愿意,可以通过传递单个参数的数据来设置 cookie。
<?php $response->setCookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httponly, $samesite);
- deleteCookie($name = ''[, $domain = ''[, $path = '/'[, $prefix = '']]])
- 参数:
$name (
mixed
) – Cookie 名称或参数数组$domain (
string
) – Cookie 域名$path (
string
) – Cookie 路径$prefix (
string
) – Cookie 名称前缀
- 返回类型:
void
删除现有 cookie。
注意
这也只是设置浏览器 cookie 以删除 cookie。
仅需要
name
。prefix
仅在您需要避免与服务器上其他同名 cookie 发生名称冲突时才需要。如果 cookie 应该仅针对该子集删除,请提供
prefix
。如果 cookie 应该仅针对该域删除,请提供domain
名称。如果 cookie 应该仅针对该路径删除,请提供path
名称。如果任何可选参数为空,则将删除所有适用的同名 cookie。
示例
<?php $response->deleteCookie($name);
- hasCookie($name = ''[, $value = null[, $prefix = '']])
- 参数:
$name (
mixed
) – Cookie 名称或参数数组$value (
string
) – cookie 值$prefix (
string
) – Cookie 名称前缀
- 返回类型:
bool
检查响应中是否包含指定的 cookie。
注意
仅需要
name
。如果指定了prefix
,它将被附加到 cookie 名称之前。如果没有给出
value
,该方法只检查名为 cookie 的存在。如果给出了value
,则该方法检查 cookie 是否存在,以及它是否具有规定的值。示例
<?php if ($response->hasCookie($name)) { // ... }
- getCookie($name = ''[, $prefix = ''])
- 参数:
$name (
string
) – Cookie 名称$prefix (
string
) – Cookie 名称前缀
- 返回类型:
Cookie|Cookie[]|null
如果找到,则返回命名的 cookie,否则返回
null
。如果没有给出name
,则返回Cookie
对象的数组。示例
<?php $cookie = $response->getCookie($name);
- getCookies()
- 返回类型:
Cookie[]
返回当前在 Response 实例中设置的所有 cookie。这些是您在当前请求中专门指定设置的任何 cookie。