Not getting expected response from Guzzle

2020-08-09 07:48发布

问题:

I'm trying to build an endpoint that forwards the data passed to it to an API using the Slim PHP Framework and I'm having trouble getting my response from a Guzzle request.

$app->map( '/api_call/:method', function( $method ) use( $app ){
    $client = new GuzzleHttp\Client([
        'base_url' => $app->config( 'api_base_url' ),
        'defaults' => [
            'query'   => [ 'access_token' => 'foo' ],
        ]
    ]);

    $request = $client->createRequest( $app->request->getMethod(), $method, [
        'query' => $app->request->params()
    ]);

    var_dump( $client->send( $request )->getBody() );

})->via( 'GET', 'POST', 'PUT', 'PATCH', 'DELETE' )->conditions( [ 'route' => '.+?' ] );`

This then gives me...

object(GuzzleHttp\Stream\Stream)[59]
  private 'stream' => resource(72, stream)
  private 'size' => null
  private 'seekable' => boolean true
  private 'readable' => boolean true
  private 'writable' => boolean true
  private 'meta' => 
    array (size=6)
     'wrapper_type' => string 'PHP' (length=3)
      'stream_type' => string 'TEMP' (length=4)
      'mode' => string 'w+b' (length=3)
      'unread_bytes' => int 0
      'seekable' => boolean true
      'uri' => string 'php://temp' (length=10)

...instead of the response of 'cool' I was expecting.

If I just var_dump $client->sendRequest( $request ) I get a 200 OK, and the url is what I expect, http://localhost:8000/test?access_token=foo.

I have another request, but only using $client->post(...) and it works fine without giving me the stream thing back.

I've tried reading the stream using the example at the bottom (http://guzzle.readthedocs.org/en/latest/http-client/response.html) but it's telling me feof doesn't exist.

Anyone have any idea what I'm missing or doing wrong here?

回答1:

The body that you are var_dumping is a Guzzle stream object. This object can be treated like a string or read from as needed. Documentation for Guzzle Stream here



回答2:

Could be;

$response = $client->send($request)->getBody()->getContents();
$response = $client->send($request)->getBody()->read(1024*100000);

This also work as a shorthand;

$response = ''. $client->send($request)->getBody();
$response = (string) $client->send($request)->getBody();

// see __toString() method for last examples: http://php.net/manual/en/language.oop5.magic.php#object.tostring



回答3:

I was having the same issue, and the thing is, if you getBody its a stream, which means it has a pointer, when you do getContents on it its leaving the pointer in the end of the file, which means if you want to get the body multiple times you need to seek the pointer back to 0.

$html1 = $this->response->getBody()->getContents();
$this->response->getBody()->seek(0);
$html2 = $this->response->getBody()->getContents();
$this->response->getBody()->seek(0);

This should work :)

@mrW I hope this helps you



回答4:

Just had a strange situation. Note that you can get body content only once!

I have expected to get same content every time I call getContents().

$html1 = $this->response->getBody()->getContents();
$html2 = $this->response->getBody()->getContents();

$same = ($html1 == $html2);

strlen($html1); //x
strlen($html2); //0

But they are not! I have missed information that Guzzle response is stream so with first getContents() we read all contents and nothing is left for second call.