php - psr7 - Cómo leer la URL efectiva de respuesta en Guzzle ~ 6.0
psr7 php (6)
He estado buscando durante aproximadamente 2 horas y no puedo entender cómo leer la respuesta final uri.
En versiones anteriores de PHP Guzzle , simplemente llama a $response->getEffectiveUrl()
y lo obtiene.
Esperaba tener algo similar en la nueva versión para que el código final se vea así:
$response = $httpClient->post(''http://service.com/login'', [
''form_params'' => [
''user'' => $user,
''padss'' => $pass,
]
]);
$url = $response->getEffectiveUrl();
Pero en la última versión, $response
ahora es un GuzzleHttp/Psr7/Response
y no hay ningún método que me permita recuperar el uri.
Leí sobre las redirecciones aquí ( http://guzzle.readthedocs.org/en/latest/quickstart.html#redirects ) pero no dice nada sobre
ACTUALIZACIÓN: La versión 6.1 ahora le permite hacer esto fácilmente:
https://stackoverflow.com/a/35443523/1811887
Gracias @YauheniPrakopchyk
Creo que es mejor usar encabezados de respuesta para almacenar esta información. Escribí una clase simple que guarda la url efectiva en X-GUZZLE-EFFECTIVE-URL
:
Uso:
<?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'');
Estoy usando middleware para rastrear solicitudes en la cadena de redireccionamiento y guardar la última. El uri de la última solicitud es lo que quieres.
Prueba este código:
$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://.com'');
$response = $client->send($request);
var_dump($lastRequest->getUri()->__toString());
Resultado:
string(24) "http://.com"
Ejemplo con clase:
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://.com'');
$response = $client->send($request);
var_dump($effectiveYrlMiddleware->getLastRequest()->getUri()->__toString());
La respuesta aceptada no me funcionó, pero me guió en el camino:
$client = new /GuzzleHttp/Client();
$client->request(''GET'', $url, [
''on_stats'' => function (/GuzzleHttp/TransferStats $stats) {
echo($stats->getHandlerStats()[''redirect_url'']);
}
]);
No soy un experto en el tema pero, por lo que entiendo, la url efectiva no es algo que se define en un mensaje HTTP general. Creo que es algo relacionado con Curl y, como Guzzle puede usar cualquier controlador HTTP para enviar solicitudes ( consulte aquí ), la información no está necesariamente presente.
Puede verificar qué redirecciones su solicitud tenía mediante la configuración del parámetro 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));
Si hubo algún redireccionamiento, el último debe ser su URL efectiva o, de lo contrario, su URL inicial.
Puede leer más sobre allow_redirects
aquí http://docs.guzzlephp.org/en/latest/request-options.html#allow-redirects .
Solución de Guzzle 6.1 directamente de los 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