Guzzle 6:没有更多的json()方法用于响应

时间:2015-05-29 12:53:20

标签: php guzzle

以前在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']);

或者是否有帮助者或类似的东西?

6 个答案:

答案 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功能的解决方法:

  1. 创建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;
        }
    }
    
  2. 创建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()


陷阱

  1. json_decode($response->getBody()并不是最佳解决方案,因为它神奇地将流转换为字符串。 json_decode()需要将字符串作为第一个参数。
  2. 除非您知道自己在做什么,否则请不要使用$response->getBody()->getContents()。如果您阅读getContents()的文档,则显示为:Returns the remaining contents in a string。因此,调用getContents()会读取流的其余部分,然后再次调用则不会返回任何内容,因为流已经在末尾了。您必须在这些呼叫之间倒回流。