How to read the response effective URL in Guzzle ~6.0

后端 未结 6 1974
我寻月下人不归
我寻月下人不归 2020-12-24 01:26

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

相关标签:
6条回答
  • 2020-12-24 01:51

    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
    
    0 讨论(0)
  • 2020-12-24 01:53

    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']);
        }
    ]);
    
    0 讨论(0)
  • 2020-12-24 02:05

    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.

    0 讨论(0)
  • 2020-12-24 02:07

    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());
    
    0 讨论(0)
  • 2020-12-24 02:12

    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.

    0 讨论(0)
  • 2020-12-24 02:15

    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:

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

    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');
    
    0 讨论(0)
提交回复
热议问题