Comment lire L'URL efficace de réponse dans Guzzle ~6.0

j'ai cherché pendant 2 heures, et je ne peux pas comprendre comment lire la réponse finale de l'uri.

dans les versions précédentes de PHP Bouffer vous suffit d'appeler $response->getEffectiveUrl() et vous l'obtenez.

Je m'attendais à avoir quelque chose de similaire dans la nouvelle version donc le code final ressemble à ceci:

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

$url = $response->getEffectiveUrl();

Mais dans la dernière version $response est un GuzzleHttpPsr7Response et il n'y a pas de méthode qui me permettent de récupérer l'uri.

j'ai lu à propos du redirections ici (http://guzzle.readthedocs.org/en/latest/quickstart.html#redirects) mais cela ne dit rien à propos de

mise à jour: la version 6.1 vous permet maintenant de le faire facilement:

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

Merci @YauheniPrakopchyk

27
demandé sur Community 2015-06-06 14:31:48

6 réponses

Bouffer 6.1 solution de droit de l' docs.

$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
40
répondu Yauheni Prakopchyk 2016-07-13 16:52:14

vous pouvez vérifier quelles redirections votre requête avait le paramètre byttrack_redirects paramètre:

$client = new \GuzzleHttp\Client(['allow_redirects' => ['track_redirects' => true]]);

$response = $client->request('GET', 'http://example.com');

var_dump($response->getHeader(\GuzzleHttp\RedirectMiddleware::HISTORY_HEADER));

S'il y a eu une redirection en dernier, celle-ci devrait être votre url effective de l'autre côté de votre url initiale.

vous pouvez en savoir plus sur allow_redirects ici http://docs.guzzlephp.org/en/latest/request-options.html#allow-redirects.

13
répondu bgaluszka 2015-11-16 10:18:42

j'utilise middleware pour suivre les requêtes dans la chaîne de redirection et enregistrer la dernière. L'uri de la dernière demande est ce que vous voulez.

Essayez ce 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());

Résultat:

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

Exemple avec la classe:

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
répondu Евгений Грицай 2015-07-08 08:23:17

je pense qu'il est préférable d'utiliser des en-têtes de réponse à stocker cette information. J'ai écrit une classe simple qui sauve efficace url X-GUZZLE-EFFECTIVE-URL header:

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

Utilisation:

<?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
répondu Artur Bodera 2015-08-12 10:27:58

Accepté de répondre ne fonctionne pas pour moi, mais m'a conduit sur le chemin:

$client = new \GuzzleHttp\Client();
$client->request('GET', $url, [
    'on_stats' => function (\GuzzleHttp\TransferStats $stats) {
        echo($stats->getHandlerStats()['redirect_url']);
    }
]);
3
répondu Sebastien Horin 2017-02-16 17:04:08

Je ne suis pas un expert en la matière mais, d'après ce que j'ai compris, l'url efficace n'est pas quelque chose qui est défini dans un message HTTP général. Je pense que c'est quelque chose qui est lié à Curl et puisque Guzzle peut utiliser n'importe quel gestionnaire HTTP pour envoyer des requêtes (voir ici), l'information n'est pas nécessairement présente.

-1
répondu marcosh 2015-06-06 14:03:14