以前在Guzzle 5.3中:
$response = $client->get('http://httpbin.org/get');
$array = $response->json(); // Yoohoo
var_dump($array[0]['origin']);
我可以轻松地从JSON响应中获取PHP数组。现在在Guzzle 6中,我不知道该怎么做。似乎没有json()
方法了。我(很快)从最新版本中读取了文档,但没有发现任何有关JSON响应的信息。我想我错过了一些东西,也许有一个我不理解的新概念(或者我没有正确阅读)。
这是(以下)新方式的唯一途径吗?
$response = $client->get('http://httpbin.org/get');
$array = json_decode($response->getBody()->getContents(), true); // :'(
var_dump($array[0]['origin']);
或者是否有帮助者或类似的东西?
答案 0 :(得分:242)
我现在使用json_decode($response->getBody())
代替$response->json()
。
我怀疑这可能是PSR-7合规性的牺牲品。
答案 1 :(得分:96)
切换到:
json_decode($response->getBody(), true)
如果您希望它与以前完全一样工作以获取数组而不是对象,则代替其他注释。
答案 2 :(得分:18)
我使用$response->getBody()->getContents()
从响应中获取JSON。
Guzzle版本6.3.0。
答案 3 :(得分:4)
如果你们仍然感兴趣,这是我基于Guzzle middleware功能的解决方法:
创建JsonAwaraResponse
,它将通过Content-Type
HTTP标头对JSON响应进行解码(如果不是),它将作为标准的Guzzle响应:
<?php
namespace GuzzleHttp\Psr7;
class JsonAwareResponse extends Response
{
/**
* Cache for performance
* @var array
*/
private $json;
public function getBody()
{
if ($this->json) {
return $this->json;
}
// get parent Body stream
$body = parent::getBody();
// if JSON HTTP header detected - then decode
if (false !== strpos($this->getHeaderLine('Content-Type'), 'application/json')) {
return $this->json = \json_decode($body, true);
}
return $body;
}
}
创建Middleware,它将用上述Response实现替换Guzzle PSR-7响应:
<?php
$client = new \GuzzleHttp\Client();
/** @var HandlerStack $handler */
$handler = $client->getConfig('handler');
$handler->push(\GuzzleHttp\Middleware::mapResponse(function (\Psr\Http\Message\ResponseInterface $response) {
return new \GuzzleHttp\Psr7\JsonAwareResponse(
$response->getStatusCode(),
$response->getHeaders(),
$response->getBody(),
$response->getProtocolVersion(),
$response->getReasonPhrase()
);
}), 'json_decode_middleware');
在此之后,将JSON作为PHP本机数组来检索,像往常一样使用Guzzle:
$jsonArray = $client->get('http://httpbin.org/headers')->getBody();
使用guzzlehttp / guzzle 6.3.3测试
答案 4 :(得分:1)
添加->getContents()
不会返回jSON响应,而是以文本形式返回。
您可以简单地使用json_decode
答案 5 :(得分:0)
$response
是PSR-7 ResponseInterface
的实例。有关更多详细信息,请参见https://www.php-fig.org/psr/psr-7/#3-interfaces
getBody()
返回StreamInterface
:
/**
* Gets the body of the message.
*
* @return StreamInterface Returns the body as a stream.
*/
public function getBody();
StreamInterface
实现了__toString()
,
从头到尾将流中的所有数据读取为字符串。
因此,要将正文读取为字符串,必须将其强制转换为字符串:
$stringBody = (string) $response->getBody()
json_decode($response->getBody()
并不是最佳解决方案,因为它神奇地将流转换为字符串。 json_decode()
需要将字符串作为第一个参数。$response->getBody()->getContents()
。如果您阅读getContents()
的文档,则显示为:Returns the remaining contents in a string
。因此,调用getContents()
会读取流的其余部分,然后再次调用则不会返回任何内容,因为流已经在末尾了。您必须在这些呼叫之间倒回流。