如果未设置超时,为什么cURL连接失败(没有错误)?

4 php curl timeout

我有一个PHP脚本,该脚本通过cURL连接到URL,然后根据返回的HTTP状态代码执行某些操作:

$ch = curl_init();
$options = array(
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_URL            => $url,
            CURLOPT_USERAGENT      => "What?!?"
);
curl_setopt_array($ch, $options);
$out = curl_exec($ch);
$code = curl_getinfo($ch)["http_code"];
curl_close($ch);

if ($code == "200") {
    echo "200";
} else {
   echo "not 200";
}
Run Code Online (Sandbox Code Playgroud)

某些Web服务器的回复速度很慢,尽管在我的脚本尝试连接到该服务器几秒钟后,网页已加载到我的浏览器中时,它告诉我它没有收到肯定的答复(“ 200”)。因此,显然,cURL发起的连接超时。

但为什么?我没有在脚本中设置超时,并且根据该站点上其他答案,cURL的默认超时时间肯定比页面在浏览器中加载所需的三到四秒长。

那么,为什么连接超时了?如果显然已经将其设置为无限,我又如何才能使其持续更长的时间呢?


笔记:

  • 相同的URL并不总是超时。因此,有时cURL 可以连接。
  • 有时不是一个特定的URL超时,而是在不同的时间使用不同的URL。
  • 我在共享服务器上,因此我无权访问任何文件。
  • 我尝试查看curl_getinfo($ch)curl_error($ch)按照注释中的@ drew010的建议进行操作,但是无论何时发生问题,两者都为空。
  • 整个脚本运行一分钟多一点。此时,它成功连接到300多个URL。即使其中一个URL失败,其他连接也会成功建立。因此脚本不会超时。
  • cURL也不超时,因为当我尝试使用睡眠59秒钟的脚本连接到URL时,cURL成功连接。因此,显然,失败的URL的速度慢本身并不是cURL的问题。

更新资料

遵循@Karlos的建议,我使用了:

CURLOPT_VERBOSE        => 1,
CURLOPT_STDERR         => $curl_log
Run Code Online (Sandbox Code Playgroud)

(使用此答案中的代码),并在$curl_logURL失败(URL和IP更改)时找到以下内容:

* About to connect() to www.somesite.com port 80 (#0)
*   Trying 104.16.37.249... * connected
* Connected to www.somesite.com (104.16.37.249) port 80 (#0)
GET /wp_german/?feed=rss2 HTTP/1.1
User-Agent: myURL
Host: www.somesite.com
Accept: */*

* Recv failure: Connection reset by peer
* Closing connection #0
Run Code Online (Sandbox Code Playgroud)

所以,我找到了原因 –谢谢@Karlos!– @Axalix显然是正确的,这是网络问题。现在,我将按照本网站上针对此类故障的建议进行操作。感谢大家的帮助!

Evh*_*vhz 5

我使用curl的经验表明,有时使用该选项时:

CURLOPT_RETURNTRANSFER => true
Run Code Online (Sandbox Code Playgroud)

服务器可能没有给出成功的答复,或者至少在curl必须接收响应并将其缓存的时间范围内未给出成功的答复,因此curl将结果返回到您分配的变量中。在您的代码中:

$out = curl_exec($ch);
Run Code Online (Sandbox Code Playgroud)

在此stackoverflow问题中,将CURLOPT_RETURNTRANSFER设置为true在托管服务器上不起作用,您可以看到选项CURLOPT_RETURNTRANSFER直接受请求的主机Web服务器实现影响。

当您显式使用响应主体,并且代码依赖于响应标头时,解决此问题的一种好方法可能是:

CURLOPT_RETURNTRANSFER => false
Run Code Online (Sandbox Code Playgroud)

并执行curl代码以处理响应标头。

一旦有了您感兴趣的代码的标头,就可以运行一个PHP脚本,该脚本回显curl响应并自己解析:

<?php
    $url=isset($_GET['url']) ? $_GET['url'] : 'http://www.example.com';
    $ch= curl_init();
    $options = array(
            CURLOPT_RETURNTRANSFER => false,
            CURLOPT_URL            => $url,
            CURLOPT_USERAGENT      => "myURL"
    );
    curl_setopt_array($ch, $options);
    curl_exec($ch);
    curl_close($ch);
?>
Run Code Online (Sandbox Code Playgroud)

在任何情况下,你的问题的答复,为什么你的要求没有得到一个错误,我想的是,使用该选项CURLOPT_NOSIGNAL和不同的超时选项的解释set_opt PHP手册可能让你更接近它。

为了进一步挖掘,选项CURLOPT_VERBOSE可以帮助您通过STDERR获得有关请求行为的更多信息。