我正在使用Guzzle打开url-s列表并获取标题。一些网址花了太长时间才响应,无法打开,我想忽略它们。在Guzzle引发异常之前,我需要20秒才能完成此操作并将连接时间限制为2秒。我有这个代码,但它仍然需要更长的时间:
<?php
include 'vendor/autoload.php';
$start = new \DateTime("now");
$start = $start->format("d.m.Y H:i:s");
echo $start."\n";
$client = new Guzzle\Http\Client();
Guzzle\Http\StaticClient::mount();
try {
$request = $client->get('http://takestoolongexample', [], ['connect_timeout' => 2, 'timeout' => 3, 'debug' => true]);
$response = $request->send();
var_dump($response->getStatusCode());
} catch (Exception $e) {
echo "\n".$e->getMessage()."\n";
}
$end = new \DateTime("now");
$end = $end->format("d.m.Y H:i:s");
echo "\n".$end."\n";
?>
这是一个示例结果。如你所见,花了13秒。
$ php test.php
30.12.2013 22:00:07
* getaddrinfo(3) failed for takestoolongexample:80
* Couldn't resolve host 'takestoolongexample'
* Closing connection 0
[curl] 6: Couldn't resolve host 'http://takestoolongexample' http://takestoolongexample
30.12.2013 22:00:20
(http://takestoolongexample
是一个真正的网址,在这里改了)
这是Guzzle版本(Guzzle 4)针对此问题的更新解决方案。
$request = $client->get(sprintf("%s/noisesize.api", $this->noiseConfig->url), [
'timeout' => 5, // Response timeout
'connect_timeout' => 5, // Connection timeout
]);
投掷Guzzle\Http\Exception\RequestException
最新版本的文档在这里:Guzzle request options - connect_timeout,timeout。
精度很小,您还可以在Client构造函数上定义超时
$client = new Guzzle\Http\Client('', array(
'request.options' => array (
'timeout' => 6,
'connect_timeout' => 6
)
));
它对从此客户端发出的所有请求都有效
我知道如何在Guzzle中做到这一点的唯一方法是:
$params = array(
'command.request_options' = array(
'timeout' => 5,
'connect_timeout' => 2
)
);
$client = new Client();
$description = ServiceDescription::factory('/path/to/service/description/file');
$client->setDescription($description);
$command = $client->getCommand('commandName', $params);
$command->prepare();
$client->execute($command);
乍一看,Guzzle的文档似乎非常好,但我认为它很糟糕,令人困惑和不完整。所以,对我来说,很难弄清楚你的代码是否真的正确以及它是否应该有效。
你的例子是正确的,但它总会失败。
错误发生在cURL级别,而不是Guzzle。在发送HTTP请求(Guzzle的工作)之前,您需要建立相关的IP会话(cURL的一个)。要获得IP会话,必须在发送数据包之前进行DNS转换。
在您的示例中,DNS解析失败。它发生在cURL代码中,而不是Guzzle代码。因此,不会使用您的超时值。
如果您的真实URL仍然存在此错误,您可以在您的guzzle请求之前添加一个测试,以检查DNS是否已解决。或者您可以定义以下cURL选项:CURLOPT_CONNECTTIMEOUT或CURLOPT_CONNECTTIMEOUT_MS(请参阅http://php.net/manual/en/function.curl-setopt.php)
在使用guzzle客户端之前设置dns解决超时
putenv('RES_OPTIONS=retrans:1 retry:1 timeout:1 attempts:1'); //dns resolve params
$request = $client->get(sprintf("%s/noisesize.api", $this->noiseConfig->url),
array(
'timeout' => 5, // Response timeout
'connect_timeout' => 5, // Connection timeout
));