Не получил ожидаемого ответа от Guzzle

Я пытаюсь создать конечную точку, которая пересылает переданные ей данные в API с помощью Slim PHP Framework, и у меня возникают проблемы с получением ответа на запрос Guzzle.

$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' => '.+?' ] );`

Это дает мне ...

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)

... вместо ответа «круто», которого я ожидал.

Если я просто использую var_dump $client->sendRequest( $request ), я получаю 200 ОК, а URL-адрес - то, что я ожидал, http://localhost:8000/test?access_token=foo.

У меня есть еще один запрос, но только с использованием $client->post(...), и он отлично работает, не возвращая мне поток.

Я пробовал читать поток, используя пример внизу (http://guzzle.readthedocs.org/en/latest/http-client/response.html), но он сообщает мне, что feof не существует.

Кто-нибудь знает, что мне здесь не хватает или что я делаю неправильно?


person Johnathan Barrett    schedule 02.04.2014    source источник
comment
Возможный дубликат http://stackoverflow.com/questions/30549226/guzzlehttp-how-get-the-body-of-a-response-from-guzzle-6   -  person kenorb    schedule 29.09.2016


Ответы (4)


Тело, которое вы используете var_dumping, является объектом потока Guzzle. Этот объект можно рассматривать как строку или читать из него по мере необходимости. Документация для Guzzle Stream здесь

person Michael Dowling    schedule 03.04.2014
comment
Да, но этого не должно быть, я не это пытаюсь делать. - person Johnathan Barrett; 03.04.2014
comment
Извините, я глупый и читаю правильно. Теперь все в порядке. Спасибо. - person Johnathan Barrett; 03.04.2014

Может быть;

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

Это также работает как стенография;

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

// последние примеры см. в методе __toString(): http://php.net/manual/en/language.oop5.magic.php#object.tostring

person K-Gun    schedule 12.02.2015

У меня была такая же проблема, и дело в том, что если вы получаетеBody, это поток, что означает, что у него есть указатель, когда вы делаете на нем getContents, он оставляет указатель в конце файла, что означает, что если вы хотите получить тело несколько раз вам нужно найти указатель обратно на 0.

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

Это должно работать :)

@mrW Надеюсь, это вам поможет

person Renato Mefi    schedule 10.09.2015
comment
Спасибо! Да, в некоторых случаях это поможет. - person Vladimir Vukanac; 28.09.2015

Просто была странная ситуация. Учтите, что вы можете получить содержимое тела только один раз!

Я ожидал, что буду получать один и тот же контент каждый раз, когда звоню getContents().

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

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

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

Но это не так! Я пропустил информацию о том, что ответ Guzzle - stream, поэтому при первом getContents() мы читаем все содержимое, и ничего не остается для второго вызова.

person Vladimir Vukanac    schedule 26.04.2015