Guzzle 6:不再有 json() 响应方法
Guzzle 6: no more json() method for responses
以前在 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']);
或者有帮手之类的吗?
我现在使用 json_decode($response->getBody())
而不是 $response->json()
。
我怀疑这可能是 PSR-7 合规性的牺牲品。
您切换到:
json_decode($response->getBody(), true)
如果您希望它完全像以前一样工作以获取数组而不是对象,而不是其他注释。
我使用 $response->getBody()->getContents()
从响应中获取 JSON。
Guzzle 版本 6.3.0.
添加 ->getContents()
不会 return jSON 响应,而是 return 作为文本。
您可以简单地使用 json_decode
如果你们仍然感兴趣,这是我基于 Guzzle middleware 功能的解决方法:
创建 JsonAwaraResponse
将通过 Content-Type
HTTP header 解码 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 将用上述响应实现替换 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
$response
是 PSR-7 ResponseInterface
的实例。有关详细信息,请参阅 https://www.php-fig.org/psr/psr-7/#3-interfaces
getBody()
returns StreamInterface
:
/**
* Gets the body of the message.
*
* @return StreamInterface Returns the body as a stream.
*/
public function getBody();
StreamInterface
实现 __toString()
而
Reads all data from the stream into a string, from the beginning to end.
因此,要将正文读取为字符串,您必须将其转换为字符串:
$stringBody = (string) $response->getBody()
陷阱
json_decode($response->getBody()
不是最好的解决方案,因为它会神奇地将流转换为字符串。 json_decode()
需要字符串作为第一个参数。
- 除非您知道自己在做什么,否则不要使用
$response->getBody()->getContents()
。如果您阅读 getContents()
的文档,它会说:Returns the remaining contents in a string
。因此,调用 getContents()
读取流的其余部分并再次调用它 returns 什么都没有,因为流已经在末尾了。您必须在这些调用之间倒回流。
以前在 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']);
或者有帮手之类的吗?
我现在使用 json_decode($response->getBody())
而不是 $response->json()
。
我怀疑这可能是 PSR-7 合规性的牺牲品。
您切换到:
json_decode($response->getBody(), true)
如果您希望它完全像以前一样工作以获取数组而不是对象,而不是其他注释。
我使用 $response->getBody()->getContents()
从响应中获取 JSON。
Guzzle 版本 6.3.0.
添加 ->getContents()
不会 return jSON 响应,而是 return 作为文本。
您可以简单地使用 json_decode
如果你们仍然感兴趣,这是我基于 Guzzle middleware 功能的解决方法:
创建
JsonAwaraResponse
将通过Content-Type
HTTP header 解码 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 将用上述响应实现替换 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
$response
是 PSR-7 ResponseInterface
的实例。有关详细信息,请参阅 https://www.php-fig.org/psr/psr-7/#3-interfaces
getBody()
returns StreamInterface
:
/**
* Gets the body of the message.
*
* @return StreamInterface Returns the body as a stream.
*/
public function getBody();
StreamInterface
实现 __toString()
而
Reads all data from the stream into a string, from the beginning to end.
因此,要将正文读取为字符串,您必须将其转换为字符串:
$stringBody = (string) $response->getBody()
陷阱
json_decode($response->getBody()
不是最好的解决方案,因为它会神奇地将流转换为字符串。json_decode()
需要字符串作为第一个参数。- 除非您知道自己在做什么,否则不要使用
$response->getBody()->getContents()
。如果您阅读getContents()
的文档,它会说:Returns the remaining contents in a string
。因此,调用getContents()
读取流的其余部分并再次调用它 returns 什么都没有,因为流已经在末尾了。您必须在这些调用之间倒回流。