Как прочитать эффективный URL ответа в Guzzle ~ 6.0

Я искал около 2 часов, и я не могу понять, как читать окончательный ответ uri.

В предыдущих версиях PHP Guzzle вы просто вызываете $response->getEffectiveUrl() и получаете его.

Я ожидал, что в новой версии будет что-то похожее, так что окончательный код выглядит следующим образом:

 $response = $httpClient->post('http://service.com/login', [ 'form_params' => [ 'user' => $user, 'padss' => $pass, ] ]); $url = $response->getEffectiveUrl(); 

Но в последней версии $response теперь есть GuzzleHttp\Psr7\Response и нет способа, позволяющего мне получить uri.

Я читал о переадресациях здесь ( http://guzzle.readthedocs.org/en/latest/quickstart.html#redirects ), но он ничего не говорит о

ОБНОВЛЕНИЕ: версия 6.1 теперь позволяет вам легко сделать это:

https://stackoverflow.com/a/35443523/1811887

Спасибо @YauheniPrakopchyk

Solutions Collecting From Web of "Как прочитать эффективный URL ответа в Guzzle ~ 6.0"

Решение Guzzle 6.1 прямо из документов .

 $client = new \GuzzleHttp\Client(); $client->get('http://some.site.com', [ 'query' => ['get' => 'params'], 'on_stats' => function (TransferStats $stats) use (&$url) { $url = $stats->getEffectiveUri(); } ])->getBody()->getContents(); echo $url; // http://some.site.com?get=params 

Вы можете проверить, что перенаправляет ваш запрос на настройку параметра track_redirects :

 $client = new \GuzzleHttp\Client(['allow_redirects' => ['track_redirects' => true]]); $response = $client->request('GET', 'http://example.com'); var_dump($response->getHeader(\GuzzleHttp\RedirectMiddleware::HISTORY_HEADER)); 

Если бы были какие-либо переадресации, последним должен быть ваш эффективный URL-адрес вашего первоначального URL-адреса.

Вы можете узнать больше о allow_redirects здесь http://docs.guzzlephp.org/en/latest/request-options.html#allow-redirects .

Я использую промежуточное программное обеспечение для отслеживания запросов в цепочке перенаправления и сохранения последнего. Ури последнего запроса – это то, что вы хотите.

Попробуйте этот код:

 $stack = \GuzzleHttp\HandlerStack::create(); $lastRequest = null; $stack->push(\GuzzleHttp\Middleware::mapRequest(function (\Psr\Http\Message\RequestInterface $request) use(&$lastRequest) { $lastRequest = $request; return $request; })); $client = new Client([ 'handler' => $stack, \GuzzleHttp\RequestOptions::ALLOW_REDIRECTS => true ]); $request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org/redirect-to?url=http://stackoverflow.com'); $response = $client->send($request); var_dump($lastRequest->getUri()->__toString()); 

Результат:

 string(24) "http://stackoverflow.com" 

Пример с классом:

 class EffectiveUrlMiddleware { /** * @var \Psr\Http\Message\RequestInterface */ private $lastRequest; /** * @param \Psr\Http\Message\RequestInterface $request * * @return \Psr\Http\Message\RequestInterface */ public function __invoke(\Psr\Http\Message\RequestInterface $request) { $this->lastRequest = $request; return $request; } /** * @return \Psr\Http\Message\RequestInterface */ public function getLastRequest() { return $this->lastRequest; } } $stack = \GuzzleHttp\HandlerStack::create(); $effectiveYrlMiddleware = new EffectiveUrlMiddleware(); $stack->push(\GuzzleHttp\Middleware::mapRequest($effectiveYrlMiddleware)); $client = new Client([ 'handler' => $stack, \GuzzleHttp\RequestOptions::ALLOW_REDIRECTS => true ]); $request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org/redirect-to?url=http://stackoverflow.com'); $response = $client->send($request); var_dump($effectiveYrlMiddleware->getLastRequest()->getUri()->__toString()); 

Я думаю, что лучше использовать заголовки ответов для хранения этой информации. Я написал простой класс, который сохраняет эффективный url в X-GUZZLE-EFFECTIVE-URL :

https://gist.github.com/Thinkscape/43499cfafda1af8f606d

Применение:

 <?php use GuzzleHttp\Client; use Thinkscape\Guzzle\EffectiveUrlMiddleware; // Add the middleware to stack and create guzzle client $stack = HandlerStack::create(); $stack->push(EffectiveUrlMiddleware::middleware()); $client = new Client(['handler' => $stack]); // Test it out! $response = $client->get('http://bit.ly/1N2DZdP'); echo $response->getHeaderLine('X-GUZZLE-EFFECTIVE-URL'); 

Принятый ответ не помог мне, но повел меня по пути:

 $client = new \GuzzleHttp\Client(); $client->request('GET', $url, [ 'on_stats' => function (\GuzzleHttp\TransferStats $stats) { echo($stats->getHandlerStats()['redirect_url']); } ]); 

Я не эксперт в этой теме, но, насколько я понимаю, эффективный url не является тем, что определено в общем HTTP-сообщении. Я думаю, что это связано с Curl, и поскольку Guzzle может использовать любой обработчик HTTP для отправки запросов ( см. Здесь ), информация не обязательно присутствует.