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

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

В предыдущих версиях PHP пропивать просто позвони $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

28

Решение

Решение 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
43

Другие решения

Вы можете проверить, что перенаправления вашего запроса были установлены 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.

15

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

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

$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());
7

Я думаю, что лучше всего использовать заголовки ответов для хранения этой информации. Я написал простой класс, который сохраняет эффективный 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');
5

Принятый ответ не работал для меня, но привел меня в путь:

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

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

-1
По вопросам рекламы [email protected]