回复

你的 Slim 应用程序的路由和中间件被赋予一个 PSR-7 响应对象,代表当前要返回给客户端的 HTTP 响应。响应对象实现PSR-7 ResponseInterface,您可以使用它检查和操作 HTTP 响应状态、标头和正文。

如何获取响应对象

PSR-7 响应对象作为路由回调的第二个参数注入到你的 Slim 应用程序路由中,如下所示:

<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;

require __DIR__ . '/../vendor/autoload.php';

$app = AppFactory::create();

$app->get('/hello', function (Request $request, Response $response) {
    $response->getBody()->write('Hello World');
    return $response;
});

$app->run();
图 1:将 PSR-7 响应注入应用程序路由回调。

响应状态

每个 HTTP 响应都有一个数字状态代码状态代码标识要返回给客户端的 HTTP 响应的类型。PSR-7 Response 对象的默认状态代码是200(OK)。getStatusCode()您可以使用这样的方法获取 PSR-7 Response 对象的状态码。

$status = $response->getStatusCode();
图 3:获取响应状态代码。

您可以复制一个 PSR-7 响应对象并分配一个新的状态代码,如下所示:

$newResponse = $response->withStatus(302);
图 4:创建具有新状态代码的响应。

响应头

每个 HTTP 响应都有标头。这些是描述 HTTP 响应但在响应正文中不可见的元数据。PSR-7 Response 对象提供了多种方法来检查和操作其标头。

获取所有标题

您可以使用 PSR-7 Response 对象的getHeaders()方法将所有 HTTP 响应标头作为关联数组获取。生成的关联数组的键是标头名称,其值本身是其各自标头名称的字符串值的数字数组。

$headers = $response->getHeaders();
foreach ($headers as $name => $values) {
    echo $name . ": " . implode(", ", $values);
}
图 5:获取并迭代所有 HTTP 响应标头作为关联数组。

获取一个标题

您可以使用 PSR-7 Response 对象的方法获取单个标头的值 getHeader($name)这将返回给定标头名称的值数组。请记住,一个 HTTP 标头可能有多个值!

$headerValueArray = $response->getHeader('Vary');
图 6:获取特定 HTTP 标头的值。

您还可以使用 PSR-7 Response 对象的getHeaderLine($name)方法获取一个以逗号分隔的字符串,其中包含给定标头的所有值。与方法不同 getHeader($name),此方法返回逗号分隔的字符串。

$headerValueString = $response->getHeaderLine('Vary');
图 7:获取单个标头的值作为逗号分隔的字符串。

检测标头

您可以使用 PSR-7 Response 对象的方法测试标头是否存在 hasHeader($name)

if ($response->hasHeader('Vary')) {
    // Do something
}
图 8:检测特定 HTTP 标头的存在。

设置标题

您可以使用 PSR-7 Response 对象的 withHeader($name, $value)方法设置标头值。

$newResponse = $oldResponse->withHeader('Content-type', 'application/json');
图 9:设置 HTTP 标头
提醒
Response 对象是不可变的。此方法返回具有新标头值的 Response 对象的副本。此方法是破坏性的,它会替换已与相同标头名称相关联的现有标头值。

附加标题

您可以使用 PSR-7 Response 对象的 withAddedHeader($name, $value)方法附加一个标头值。

$newResponse = $oldResponse->withAddedHeader('Allow', 'PUT');
图 10:附加 HTTP 标头
提醒
与 方法不同withHeader(),此方法将新值附加 到同一标头名称已存在的值集中。Response 对象是不可变的。此方法返回 具有附加标头值的 Response 对象的 副本。

删除标题

您可以使用 Response 对象的withoutHeader($name)方法删除标头。

$newResponse = $oldResponse->withoutHeader('Allow');
图 11:删除 HTTP 标头
提醒
Response 对象是不可变的。此方法返回 没有指定标头的 Response 对象的 副本。

回应机构

HTTP 响应通常有一个正文。

就像 PSR-7 Request 对象一样,PSR-7 Response 对象将主体实现为Psr\Http\Message\StreamInterface. StreamInterface您可以使用 PSR-7 Response 对象的方法获取 HTTP 响应主体实例getBody()getBody()如果传出 HTTP 响应长度未知或对于可用内存而言太大,则该方法更可取。

$body = $response->getBody();
图 12:获取 HTTP 响应正文

结果Psr\Http\Message\StreamInterface实例提供了以下方法来读取、迭代和写入其底层 PHP resource

  • 获取大小()
  • 告诉()
  • eof()
  • 可搜索()
  • 寻找()
  • 倒带()
  • 是可写的()
  • 写($字符串)
  • 可读()
  • 阅读($长度)
  • 获取内容()
  • 获取元数据($key = null)

大多数情况下,您需要写入 PSR-7 Response 对象。StreamInterface您可以使用write()如下方法将内容写入实例:

$body = $response->getBody();
$body->write('Hello');
图 13:将内容写入 HTTP 响应正文

您还可以用一个全新的 实例替换StreamInterfacePSR-7 Response 对象的主体。当您希望将来自远程目标(例如文件系统或远程 API)的内容通过管道传输到 HTTP 响应时,这尤其有用。你可以用它的方法替换 PSR-7 Response 对象的主体withBody(StreamInterface $body)它的参数必须是 的一个实例Psr\Http\Message\StreamInterface

use GuzzleHttp\Psr7\LazyOpenStream;

$newStream = new LazyOpenStream('/path/to/file', 'r');
$newResponse = $oldResponse->withBody($newStream);
图 14:替换 HTTP 响应正文
提醒
Response 对象是不可变的。此方法返回 包含新正文的 Response 对象的 副本。

返回 JSON

在最简单的形式中,可以使用默认的 200 HTTP 状态代码返回 JSON 数据。

$data = array('name' => 'Bob', 'age' => 40);
$payload = json_encode($data);

$response->getBody()->write($payload);
return $response
          ->withHeader('Content-Type', 'application/json');
图 15:返回带有 200 HTTP 状态代码的 JSON。

我们还可以返回带有自定义 HTTP 状态代码的 JSON 数据。

$data = array('name' => 'Rob', 'age' => 40);
$payload = json_encode($data);

$response->getBody()->write($payload);
return $response
          ->withHeader('Content-Type', 'application/json')
          ->withStatus(201);
图 16:返回带有 201 HTTP 状态代码的 JSON。
提醒
Response 对象是不可变的。此方法返回具有新 Content-Type 标头的 Response 对象的副本。这种方法是破坏性的,它取代了现有的 Content-Type 标头。

返回重定向

您可以使用Location标头重定向 HTTP 客户端。

return $response
  ->withHeader('Location', 'https://www.example.com')
  ->withStatus(302);
图 17:返回到 https://www.example.com 的重定向