狂饮6:没有更多的JSON()响应方法

先前在狂饮5.3:

$response = $client->get('http://httpbin.org/get');
$array = $response->json(); // Yoohoo
var_dump($array[0]['origin']);

我可以很容易地从JSON响应中获得一个PHP数组。现在在狂饮6中,我不知道该怎么做。似乎没有json()方法了。我(快速)阅读了最新版本的文档,但没有找到任何关于JSON响应的信息。我想我错过了一些东西,也许有一个新的概念,我不明白(或者也许我没有正确阅读)。

这条新路是唯一的路吗?

$response = $client->get('http://httpbin.org/get');
$array = json_decode($response->getBody()->getContents(), true); // :'(
var_dump($array[0]['origin']);

或者有没有帮手之类的?

134455 次浏览

我现在用json_decode($response->getBody())代替$response->json()

我怀疑这可能是PSR-7合规性的牺牲品。

您切换到:

json_decode($response->getBody(), true)

而不是其他注释,如果您希望它完全像以前一样工作,以便获得数组而不是对象。

我使用$response->getBody()->getContents()从响应中获取JSON. 狂饮版本6.3.0.

添加->getContents()不会返回JSON响应,而是以文本形式返回。

您可以简单地使用json_decode

如果你们仍然感兴趣,这里是我的解决方案,基于狂饮中间件功能:

  1. 创建JsonAwaraResponse,它将通过Content-Type HTTP头来解码JSON响应,如果没有-它将作为标准的狂饮响应:

    <?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. Create Middleware which going to replace Guzzle PSR-7 responses with above Response implementation:

    <?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');
    

After this to retrieve JSON as PHP native array use Guzzle as always:

$jsonArray = $client->get('http://httpbin.org/headers')->getBody();

使用GuzzleHTTP/Guzzle 6.3.3进行测试

$response是PSR-7ResponseInterface的实例。有关详细信息,请参见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()

将流中的所有数据从头到尾读取到字符串中。

因此,要将Body读取为String,必须将其转换为String:

$stringBody = (string) $response->getBody()


戈查斯

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