web-dev-qa-db-ja.com

Guzzleから期待どおりの応答が得られない

Slim PHP Frameworkを使用して、それに渡されたデータをAPIに転送するエンドポイントを構築しようとしていますが、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 OKが返され、URLは_http://localhost:8000/test?access_token=foo_です。

別のリクエストがありますが、$client->post(...)のみを使用しており、ストリームを返さなくても正常に機能します。

下部の例を使用してストリームを読み込もうとしましたが( http://guzzle.readthedocs.org/en/latest/http-client/response.html )、それは私にfeofは存在しません。

誰かが私がここで何が欠けているか間違っているかを知っていますか?

17

Var_dumpしている本体はGuzzleストリームオブジェクトです。このオブジェクトは文字列のように扱うことも、必要に応じて読み取ることもできます。 Guzzle Streamのドキュメントはこちら

9
Michael Dowling

になり得る;

_$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

26
K-Gun

私は同じ問題を抱えていましたが、問題は、ストリームにgetBodyがある場合(つまり、ポインターがある場合)、その上にgetContentsを実行すると、ファイルの最後にポインターが残っていること、つまり、ポインターを0に戻す必要がある場合は、本体を複数回繰り返します。

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

これはうまくいくはずです:)

@mrWこれがあなたのお役に立てば幸いです

11
Renato Mefi

ちょうど奇妙な状況がありました。ボディコンテンツは1回しか取得できないことに注意してください。

getContents()を呼び出すたびに同じコンテンツを取得することを期待していました。

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

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

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

しかし、そうではありません! Guzzleの応答がstreamであるという情報を見逃していたので、最初にgetContents()を使用して、すべてのコンテンツを読み取り、 2番目の呼び出しには何も残されません。

2