如何阅读Guzzle~6.0中的响应有效URL

时间:2015-06-06 11:31:49

标签: php guzzle psr-7

我一直在寻找大约2个小时,我无法弄清楚如何阅读最终回复uri。

在以前版本的PHP Guzzle 中,您只需拨打$response->getEffectiveUrl()就可以获得它。

我希望在新版本中有类似内容,所以最终代码如下所示:

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

$url = $response->getEffectiveUrl();

但是在最新版本中$response现在是GuzzleHttp\Psr7\Response,并且没有方法可以让我检索uri。

我在这里读到了重定向(http://guzzle.readthedocs.org/en/latest/quickstart.html#redirects),但它没有提及

更新:6.1版本现在允许您轻松执行此操作:

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

谢谢@YauheniPrakopchyk

7 个答案:

答案 0 :(得分:46)

Guzzle 6.1解决方案直接来自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

答案 1 :(得分:17)

您可以通过设置int参数

来查看重定向您的请求的内容
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)); http://docs.guzzlephp.org/en/latest/request-options.html#allow-redirects

答案 2 :(得分:7)

我正在使用中间件跟踪重定向链中的请求并保存最后一个。最后一个请求的uri就是你想要的。

试试这段代码:

$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());

结果:

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

课程示例:

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

答案 3 :(得分:6)

我认为最好使用响应标头来存储此信息。我写了一个简单的类,它在X-GUZZLE-EFFECTIVE-URL标题中保存了有效的URL:

  

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

用法:

<?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');

答案 4 :(得分:4)

接受的答案对我不起作用但引导我前往:

$client = new \GuzzleHttp\Client();
$client->request('GET', $url, [
    'on_stats' => function (\GuzzleHttp\TransferStats $stats) {
        echo($stats->getHandlerStats()['redirect_url']);
    }
]);

答案 5 :(得分:0)

您需要在Guzzle客户端中显式添加10-10-2019

[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="date", Order=6)]
public System.DateTime NOTIF_DATE 
{
    get { return this.nOTIF_DATEField; }
    set { 
           this.nOTIF_DATEField = value;
           this.RaisePropertyChanged("NOTIF_DATE");
        }
}

[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="date", Order=10)]
public System.DateTime REQ_START 
{
    get { return this.rEQ_STARTField; }
    set {
            this.rEQ_STARTField = value;
            this.RaisePropertyChanged("REQ_START");
        }
}

track_redirects可能包含...

$client = new GuzzleHttp\Client(['allow_redirects' => ['track_redirects' => true]]); $response = $client->head('http://shop.imeldas.com'); $redirects = $response->getHeader(GuzzleHttp\RedirectMiddleware::HISTORY_HEADER); $effectiveUrl = end($redirects); 元素(如果没有重定向)。

$redirects元素(如果有一个或多个重定向)。

答案 6 :(得分:-1)

我不是该主题的专家,但据我所知,有效网址不是普通HTTP消息中定义的内容。我认为是与Curl相关的东西,因为Guzzle可以使用任何HTTP处理程序来发送请求(see here),所以信息不一定存在。