Reputation: 818
I've been searching for about 2 hours and I can't figure it out how to read the final response uri.
In previous versions of PHP Guzzle you just call $response->getEffectiveUrl()
and you get it.
I expected to have something similar in the new version so the final code looks like this:
$response = $httpClient->post('http://service.com/login', [
'form_params' => [
'user' => $user,
'padss' => $pass,
]
]);
$url = $response->getEffectiveUrl();
But in the latest version $response
is now a GuzzleHttp\Psr7\Response
and there is no method which allow me to retrieve the uri.
I read about the redirects here (http://guzzle.readthedocs.org/en/latest/quickstart.html#redirects) but it says nothing about
https://stackoverflow.com/a/35443523/1811887
Thanks @YauheniPrakopchyk
Upvotes: 53
Views: 56831
Reputation: 5783
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;
$onRedirect = function(
RequestInterface $request,
ResponseInterface $response,
UriInterface $uri
) {
echo 'Redirecting! ' . $request->getUri() . ' to ' . $uri . "\n";
};
$res = $client->request('GET', '/redirect/3', [
'allow_redirects' => [
'max' => 10, // allow at most 10 redirects.
'strict' => true, // use "strict" RFC compliant redirects.
'referer' => true, // add a Referer header
'protocols' => ['https'], // only allow https URLs
'on_redirect' => $onRedirect,
'track_redirects' => true
]
]);
echo $res->getStatusCode();
// 200
echo $res->getHeaderLine('X-Guzzle-Redirect-History');
// http://first-redirect, http://second-redirect, etc...
echo $res->getHeaderLine('X-Guzzle-Redirect-Status-History');
// 301, 302, etc...
Upvotes: 0
Reputation: 10912
Guzzle 6.1 solution right from the docs.
use GuzzleHttp\Client;
use GuzzleHttp\TransferStats;
$client = new 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
Upvotes: 82
Reputation: 11067
Accepted answer didn't work for me but led me on the way:
$client = new \GuzzleHttp\Client();
$client->request('GET', $url, [
'on_stats' => function (\GuzzleHttp\TransferStats $stats) {
echo($stats->getHandlerStats()['redirect_url']);
}
]);
Upvotes: 5
Reputation: 1083
You can check what redirects your request had byt setting track_redirects
parameter:
$client = new \GuzzleHttp\Client(['allow_redirects' => ['track_redirects' => true]]);
$response = $client->request('GET', 'http://example.com');
var_dump($response->getHeader(\GuzzleHttp\RedirectMiddleware::HISTORY_HEADER));
If there were any redirects last one should be your effective url otherewise your initial url.
You can read more about allow_redirects
here http://docs.guzzlephp.org/en/latest/request-options.html#allow-redirects.
Upvotes: 25
Reputation: 1682
I think it's best to use response headers to store this information. I wrote a simple class that saves effective url in X-GUZZLE-EFFECTIVE-URL
header:
Usage:
<?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');
Upvotes: 6
Reputation: 111
I am using middleware to track requests in the redirect chain and save the last one. The uri of the last request is what you want.
Try this code:
$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());
Result:
string(24) "http://stackoverflow.com"
Example with class:
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());
Upvotes: 11
Reputation: 9008
I'm not an expert in the subject but, from what I understand, the effective url is not something that is defined in a general HTTP message. I think is is something related to Curl and since Guzzle can use any HTTP handler to send requests (see here), the information is not necessarily present.
Upvotes: -1