本文转自关于php:如何在Guzzle中读取响应有效的URL?6.0
How to read the response effective URL in Guzzle ~6.0
我已经搜索了大约2个小时,但无法弄清楚如何读取最终响应uri。
在早期版本的PHP Guzzle中,您只需调用$response->getEffectiveUrl()即可。
我希望新版本中有类似的东西,所以最终代码如下所示
$response = $httpClient->post('/login', ['form_params' => ['user' => $user,'padss' => $pass,]]);$url = $response->getEffectiveUrl();
但是在最新版本中,$response现在是GuzzleHttp\Psr7
esponse,并且没有允许我检索uri的方法。
我在这里阅读了有关重定向的信息(/en/latest/quickstart.html#redirects),但它并没有说明
更新:6.1版本现在使您可以轻松地执行此操作:
/a/35443523/1811887
谢谢@YauheniPrakopchyk
来自文档的Guzzle 6.1解决方案。
use GuzzleHttp\\Client;use GuzzleHttp\\TransferStats;$client = new Client;$client->get('', ['query' => ['get' => 'params'],'on_stats' => function (TransferStats $stats) use (&$url) {$url = $stats->getEffectiveUri();}])->getBody()->getContents();echo $url; // ?get=params
相关讨论
因此,看起来像@Евгений建议的东西,但是是内置的,对吧?
@joserobleda很难阅读。我更喜欢关闭重定向并检查位置标头是否包含大量的代码。
因此,我将您的答案标记为有效答案。对我来说,到目前为止是最好的解决方案。
必须将TransferStats编辑为\ GuzzleHttp \ TransferStats固定。
您可以检查通过设置track_redirects参数设置的重定向
$client = new \\GuzzleHttp\\Client(['allow_redirects' => ['track_redirects' => true]]);$response = $client->request('GET', '');var_dump($response->getHeader(\\GuzzleHttp\edirectMiddleware::HISTORY_HEADER));
如果有任何重定向,则最后一个应该是您的有效网址,否则应是您的初始网址。
您可以在/en/latest/request-options.html#allow-redirects上阅读有关allow_redirects的更多信息。
我正在使用中间件来跟踪重定向链中的请求并保存最后一个。最后一个请求的uri是您想要的。
试试这个代码
$stack = \\GuzzleHttp\\HandlerStack::create();$lastRequest = null;$stack->push(\\GuzzleHttp\\Middleware::mapRequest(function (\\Psr\\Http\\Message\equestInterface $request) use(&$lastRequest) {$lastRequest = $request;return $request;}));$client = new Client(['handler' => $stack,\\GuzzleHttp\equestOptions::ALLOW_REDIRECTS => true]);$request = new \\GuzzleHttp\\Psr7\equest('GET', '/redirect-to?url=');$response = $client->send($request);var_dump($lastRequest->getUri()->__toString());
响应结果
string(24)""
类的示例
class EffectiveUrlMiddleware{/*** @var \\Psr\\Http\\Message\equestInterface*/private $lastRequest;/*** @param \\Psr\\Http\\Message\equestInterface $request** @return \\Psr\\Http\\Message\equestInterface*/public function __invoke(\\Psr\\Http\\Message\equestInterface $request){$this->lastRequest = $request;return $request;}/*** @return \\Psr\\Http\\Message\equestInterface*/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\equestOptions::ALLOW_REDIRECTS => true]);$request = new \\GuzzleHttp\\Psr7\equest('GET', '/redirect-to?url=');$response = $client->send($request);var_dump($effectiveYrlMiddleware->getLastRequest()->getUri()->__toString());
相关讨论
用法看起来不错,我希望有更少的代码选项,但我真的不认为这是一种更好的方法。我认为最好使用响应头来存储此信息。我写了一个简单的类,将有效的url保存在X-GUZZLE-EFFECTIVE-URL标头中 /Thinkscape/43499cfafda1af8f606d
<?phpuse 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');
接受的答案对我不起作用,但引导我前进
$client = new \\GuzzleHttp\\Client();$client->request('GET', $url, ['on_stats' => function (\\GuzzleHttp\\TransferStats $stats) {echo($stats->getHandlerStats()['redirect_url']);}]);
相关讨论
您需要在Guzzle客户端中显式添加track_redirects。接受的答案对我没有用,这个也没有。我无法理解它们如何工作,因为CURL请求是异步的,并且会在初始PHP请求结束后发生(因此,您对某个URL进行请求,并在请求完成后回显/获取变量,但显示/访问变量来自初始线程…)。对我有用的只是将echo更改为使用Monolog。也许取决于id的Guzzle设置
这些请求是同步的。请求完成后,将执行下一行代码。
$client = new GuzzleHttp\\Client(['allow_redirects' => ['track_redirects' => true]]);$response = $client->head('');$redirects = $response->getHeader(GuzzleHttp\edirectMiddleware::HISTORY_HEADER);$effectiveUrl = end($redirects);
我不是该主题的专家,但是据我了解,有效的URL并不是一般HTTP消息中定义的内容。我认为这与Curl有关,由于Guzzle可以使用任何HTTP处理程序来发送请求(请参见此处),因此信息不一定存在$redirects可能包含…
0元素(如果没有重定向)。
1…n元素(如果一个或多个重定向)。
我知道了,但是应该有一种机制,可以让我获得该信息的任何机制,不是吗?
您可能会使用类似这样的东西:/manual/en/function.curl-getinfo.php,或者尝试在枪口仓库中打开一个问题并寻求帮助
现在,我可以禁用重定向并读取Location标头,但这仅在当前情况下有效。当您获得更多重定向时,这不是一个选择。