Slim 应用的路由和中间件都是通过PSR 7响应对象去返回当前HTTP响应给客户端.这个对象是 PSR 7 ResponseInterface 的实现.我们可以通过它去操作和HTTP响应的状态,头部和正文.

怎样获取响应对象

PSR 7响应对象已经作为Slim应用路由的回调函数的第二个参数被注入了,你可以直接使用:

示例:

<?php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

$app = new \Slim\App;
$app->get('/foo', function (ServerRequestInterface $request, ResponseInterface $response) {
		// Use the PSR 7 $response object

		return $response;
});
$app->run();

在Slim中间件中也是如此,第二个参数就是PSR 7响应对象:

示例:

<?php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

$app = new \Slim\App;
$app->add(function (ServerRequestInterface $request, ResponseInterface $response, callable $next) {
		// Use the PSR 7 $response object

		return $next($request, $response);
});
// Define app routes...
$app->run();

响应状态

任何一个HTTP响应都有一个数字的状态码(status code).响应状态表示返回给客户端的响应的类型.PSR 7响应对象默认的响应状态码是 200(ok).你可以通过PSR 7响应对象的方法 getStatusCode() 获取响应状态码.

$status = $response->getStatusCode();

我们也可以复制一个PSR 7响应对象,并重新给状态码一个值:

$newResponse = $response->withStatus(302);

响应头部

任何一个HTTP响应都有响应头部,响应头部作为元数据描述了HTTP响应,但是他们在响应正文里面是看不到的,Slim PSR 7提供了一些方法去操作和检查响应头部.

获取所有的头部信息

你可以通过 PSR 7响应对象的方法 getHeaders() 获取所有的头部信息,结果以索引数组形式返回.返回的索引数组键名为header名称,数组值是一个数字索引数组,header名称所表示的值

示例:

$headers = $response->getHeaders();
foreach ($headers as $name => $values) {
		echo $name . ": " . implode(", ", $values);
}

获取某一个header信息

你也可以只获取header中的一条信息,通过PSR 7响应对象的 getHeader($name) 方法.返回一个数组,数组值是$name所表示的值.但是切记,一个头部名有可能有很多条值:

示例:

$headerValueArray = $response->getHeader('Vary');

当然你也可以通过另一个PSR 7的响应对象方法 getHeaderLine($name) 获取一条信息,返回的是一个以逗号分隔的字符串:

示例:

$headerValueString = $response->getHeaderLine('Vary');

检查头部

你可以通过PSR 7响应对象的方法hasHeader($name) 判断某一条响应头是否存在

if ($response->hasHeader('Vary')) {
// Do something
}

设置头部

我们可以通过PSR 7响应对象的方法 withHeader($name, $value)设置一个响应头

$newResponse = $oldResponse->withHeader('Content-type', 'application/json');

注意:

响应对象是不可改变的.这个方法是复制一个响应对象并改变它的值,这个方式是破坏性的,它会替换掉之前已经存在的同名称的值

使用示例:由于响应对象值时不可改变的并不会有X-By http header存在

$app->get('/',function ($request, $response) {
$response->withHeader('X-By',1234);  
return $response->write('hello');
});

如果确实要添加http头部,应该如此

$app->get('/',function ($request, $response) {
$newresponse = $response->withHeader('X-By',1211);
return $newresponse->write('hello');
});

那为什么说它是破坏性的呢

$app->get('/',function ($request, $response) {
$newresponse = $response->withHeader('X-By',1234);
$new_response = $newresponse->withHeader('X-By',1034);
return $new_response->write('hello');
});

这样在响应中X-By的值为1034,会把之前的值替换掉

添加头部

你可以通过psr 7响应对象的方法 withAddedHeader($name, $value)添加一条header

$newResponse = $oldResponse->withAddedHeader('Allow', 'PUT');

注意:

不同于withHeader方法,这个方法会增加一个新值,如果你设置的header 名称已经存在的话,因为psr 7对象时不可改变的,因此在赋值的对象中会会存在新的值与旧的值。

示例:

$app->get('/',function ($request, $response) {
$newresponse = $response->withHeader('X-By',1234);
$new_response = $newresponse->withAddedHeader('X-By',1034);
return $new_response->write('hello');
});

http Header中 X-By有两条记录值分别为 1234和1034

移除Header

你可以通过PSR 7响应对象的方法 withoutHeader($name)移除某些header值

$newResponse = $oldResponse->withoutHeader('Allow');

注意:

因为PSR 7对象是不可改变的,因此也必须复制一个新的PSR 7对象。

响应正文

一个HTTP响应一般都有响应正文,Slim 提供一个PSR7响应对象去检查和操作最终的响应正文。

如果PSR7请求对象一样,PSR7响应对象操作响应正文是通过以操作接口 \Psr\Http\Message\StreamInterface 的实现的方式,你可以通过PSR7响应对象的getBody()方法获得响应正文 StreamInterface 的实例,getBody()方法更适合于输出未知长度或者不知大小的情况。

$body = $response->getBody();

\Psr\Http\Message\StreamInterface 提供了下面的方法去读取,迭代和在PHP资源下进行修改

* getSize()
* tell()
* eof()
* isSeekable()
* seek()
* rewind()
* isWritable()
* write($string)
* isReadable()
* read($length)
* getContents()
* getMetadata($key = null)

大多数情况下,你可能需要往PSR7响应对象的写入东西,你可以通过 StreamInterface 实例的方法write()实现

$body = $response->getBody();
$body->write('Hello');

你可以使用一个新的 StreamInterface 替换现在PSR7响应对象的body,这是非常有用的当你想获取内容通过远程的目的地的(例如:文件系统或者远程api)并写入响应的时候,你可以替换PSR7响应对象的body通过withBody(StreamInterface $body) 方法,但是它的参数必须是\Psr\Http\Message\StreamInterface的实现

$newStream = new \GuzzleHttp\Psr7\LazyOpenStream('/path/to/file', 'r');
$newResponse = $oldResponse->withBody($newStream);

注意:

PSR7响应对象是不可改变的,必须复制一个新的对象

文档翻译的并不是很专业,仅供个人学习作用,建议看官方文档。

如有兴趣,请看下一篇 SLIM 3 文档(九)-路由2)