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 的净化版本。

使用 Cookie 重定向

如果您在调用 redirect() 之前设置了 Cookie,它们将被设置为全局响应实例,并且不会自动复制到 RedirectResponse 实例中。

要发送 Cookie,您需要手动调用 withCookies() 方法。

// Copies all cookies from global response instance.
return redirect()->back()->withCookies();

使用 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-ControlETag 标头处理。本指南不是对所有缓存标头功能进行全面介绍的合适地方,但您可以在 Google Developers 上获得很好的理解。

默认情况下,通过 CodeIgniter 发送的所有响应对象都关闭了 HTTP 缓存。选项和确切情况过于多样,我们无法创建除关闭之外的良好默认值。通过 setCache() 方法,您可以轻松地将缓存值设置为所需的值

<?php

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

$options 数组只接受键值对数组,除了少数例外,这些键值对被分配给 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) – 可选的理由短语。

返回:

当前响应实例

返回类型:

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

告诉响应将所有内容发送回客户端。这将首先发送头部,然后发送响应主体。对于主应用程序响应,您不需要调用此方法,因为它由 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);

只有 namevalue 是必需的。要删除 cookie,请将其设置为 expire 为空。

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

注意

但是,如果 value 设置为空字符串,并且 expire 设置为 0,则 cookie 将被删除。

对于无论您的网站如何请求都适用的全站 cookie,请将您的 URL 添加到 domain 中,以句点开头,例如:.your-domain.com

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

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。