HTTP 响应

Response 类通过只适合服务器对调用它的客户端做出响应的方法来扩展 HTTP 消息类

处理响应

一个响应类已经为你实例化并传入你的控制器。它可以通过 $this->response 访问。它和 Services::response() 返回的实例是同一个。我们称之为全局响应实例。

许多时候你不需要直接接触该类,因为 CodeIgniter 会为你发送 header 和 body。如果页面成功地创建了它被要求的内容,情况就是这样。当事情出错时,或者你需要发送非常具体的状态码回应,或者利用 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() 方法将 content type header 设置为适当的 MIME 类型。通常,你会传递一个数据数组进行转换:

<?php

$data = [
    'success' => true,
    'id'      => 123,
];

return $this->response->setJSON($data);

// or
return $this->response->setXML($data);

重定向

如果你想创建一个重定向,使用 redirect() 函数。

它返回一个 RedirectResponse 实例。它是一个与 Services::response() 返回的全局响应实例不同的实例。

警告

如果你在调用 redirect() 之前设置了 Cookie 或响应头部,它们会被设置到全局响应实例,它们并不会自动复制到 RedirectResponse 实例。要发送它们,你需要手动调用 withCookies()withHeaders() 方法。

重要

如果你想要重定向,必须在 ControllerController Filter 的方法中返回 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() 与浏览器的“后退”按钮不同。 当 Session 可用时,它会将访问者带到“在 Session 期间查看的最后一页”。 如果没有加载 Session,或者 Session 不可用,那么将使用 HTTP_REFERER 的安全版本。

带 Header 的重定向

如果你在调用 redirect() 之前设置了响应头部,它们会被设置到全局响应实例,它们并不会自动复制到 RedirectResponse 实例。

要发送 Header,你需要手动调用 withHeaders() 方法。

// Copies all headers from the global response instance.
return redirect()->back()->withHeaders();

重定向状态码

GET 请求的默认 HTTP 状态码是 302。但是,当使用 HTTP/1.1 或更高版本时,对于 POST/PUT/DELETE 请求使用 303,对于所有其他请求使用 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);

备注

由于一个错误,在 v4.3.3 或更早版本中,即使指定了状态码, 实际重定向响应的状态码也可能被改变。 请参阅 ChangeLog v4.3.4

如果你不知道重定向的 HTTP 状态码,建议阅读 Redirections in HTTP

强制文件下载

Response 类提供了一种简单的方法来将文件发送给客户端,提示浏览器下载数据到计算机。这会设置适当的头使其发生。

第一个参数是 希望下载的文件的名称,第二个参数是文件数据。

如果将第二个参数设置为 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');

备注

必须返回响应对象以便下载被发送到客户端。这允许在被发送到客户端之前通过所有的 后置 过滤器来传递响应。

在浏览器中打开文件

一些浏览器可以显示诸如 PDF 等文件。为了告诉浏览器显示文件而不是保存它,调用 DownloadResponse::inline() 方法。

<?php

$data = 'Here is some text!';
$name = 'mytext.txt';

return $this->response->download($name, $data)->inline();

HTTP 缓存

内置于 HTTP 规范的是帮助客户端(通常是网页浏览器)缓存结果的工具。如果使用正确,这可以为你的应用程序带来巨大的性能提升,因为它会告诉客户端他们不需要联系服务器,因为没有变化。你再也找不到更快的了。

这是通过 Cache-ControlETag 头处理的。本指南不是适合对所有缓存头功能进行透彻的介绍,但是你可以在 Google Developers 上很好地理解它。

默认情况下,通过 CodeIgniter 发送的所有响应对象都关闭了 HTTP 缓存。由于我们无法创建一个好的默认值,除了关闭它之外的选项太多了。根据你的需要设置缓存值非常简单,可以通过 setCache() 方法完成:

<?php

$options = [
    'max-age'  => 300,
    's-maxage' => 900,
    'etag'     => 'abcde',
];
$this->response->setCache($options);

$options 数组简单地以 key/value 对的形式获取通常分配给 Cache-Control 头的数组。你可以自由地根据具体情况完全设置所需的所有选项。虽然大多数选项应用于 Cache-Control 头,但它也智能地处理 etaglast-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) – 可选的原因短语

返回:

当前的 Response 实例

返回类型:

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) – 此响应所代表的内容类型

  • $charset (string) – 此响应使用的字符集

返回:

当前响应实例

返回类型:

CodeIgniter\HTTP\Response

设置此响应所代表的内容类型:

<?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 头,包括 ETagsLast-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

告诉响应将所有内容发送回客户端。这将首先发送 header,然后是响应 body。对于主应用程序响应,你不需要调用它,因为 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 accessible 用于 HTTP 请求(无 JavaScript)。如果设置为 null,将使用 app/Config/Cookie.php 中的默认值

  • $samesite (string) – SameSite cookie 参数的值。如果设置为 '',cookie 将不设置 SameSite 属性。如果设置为 null,将使用 app/Config/Cookie.php 中的默认值

返回类型:

void

备注

在 v4.2.7 之前版本,由于一个错误, $secure$httponly 的默认值为 false, 从未使用来自 app/Config/Cookie.php 的这些值。

将包含你指定值的 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);

namevalue 是必需的。要删除 cookie,请将 expire 置空。

expire 设置,将添加到当前时间。不要包括时间,而只设置从 现在 希望 cookie 有效的秒数。如果 expire 设置为零,cookie 将只在浏览器打开时有效。

备注

但是如果同时将 value 设置为空字符串和 expire 设置为 0, cookie 将被删除。

对于无论如何请求站点的站点范围 cookie,在域名前添加站点 URL,如: .your-domain.com

通常不需要 path,因为该方法设置根路径。

仅在需要避免与服务器上其他同名 cookie 的名称冲突时才需要 prefix

仅在希望通过设置为 true 将其设置为安全 cookie 时才需要 secure 标志。

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 是必需的。

仅当需要避免与服务器上其他同名 cookie 的名称冲突时才需要 prefix

如果希望只删除该子集的 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。