PHP 有这两个与超时相关的选项:
CURLOPT_CONNECTTIMEOUT
和 CURLOPT_TIMEOUT
。
PHP 网站上的描述有点模糊。有什么区别?
使用现实世界的示例:假设您通过 cURL 将 GET 变量发送到 URL 并且希望接收返回的 XML,则
CURLOPT_CONNECTTIMEOUT
与连接到服务器所需的最长时间有关,并且 CURLOPT_TIMEOUT
发回 XML 所需的最长时间?
CURLOPT_CONNECTTIMEOUT 是允许连接到服务器的最长时间(以秒为单位)。 可以设置为 0 以禁用此限制,但在生产环境中这是不可取的。
CURLOPT_TIMEOUT 是限制单个 cURL 扩展函数调用执行的最长时间(以秒为单位)。 请注意,此设置的值应包括 CURLOPT_CONNECTTIMEOUT 的值。
换句话说, CURLOPT_CONNECTTIMEOUT 是 CURLOPT_TIMEOUT 表示的时间段,因此 CURLOPT_TIMEOUT 的值应大于 CURLOPT_CONNECTTIMEOUT 的值。
CURLOPT_CONNECTTIMEOUT 不是CURLOPT_TIMEOUT代表的一段时间
如果 CURLOPT_CONNECTTIMEOUT 设置为 3 秒,CURLOPT_TIMEOUT 设置为 4 秒,则执行可能最多需要 7 秒。
我通过模拟缓慢的服务器连接(iptables drop)来测试这一点。
CURLOPT_CONNECTTIMEOUT 是仅连接到服务器的时间。
CURLOPT_TIMEOUT 是整个连接时间加上交换数据的时间。
因此,CURLOPT_TIMEOUT 始终包含 CURLOPT_CONNECTTIMEOUT。
验证使用 CURLINFO_CONNECT_TIME 和 CURLINFO_TOTAL_TIME 是否非常容易。
curl_getinfo($ch, CURLINFO_CONNECT_TIME) 获取信息,curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $yourMaxConnTime) 设置要连接的最大值。
curl_getinfo($ch, CURLINFO_TOTAL_TIME) 获取信息,curl_setopt($ch, CURLOPT_TIMEOUT, $yourMaxTotTime) 设置整个操作的最大值。
当然,$yourMaxTotTime 必须始终高于 $yourMaxConnTime。 所有这些值均以秒为单位。
接受的答案不正确。请参阅 timeouts - Everything CURL 文档以获取正确的文档。
连接时间基本上涵盖了建立http连接的两个方面:
CURLOPT_TIMEOUT 或 CURLOPT_TIMEOUT_MS 选项根本不涵盖这段时间。这些涵盖了我们开始通过刚刚在连接阶段建立的 TCP 连接谈论 HTTP 之后发生的所有事情。
这种区别给很多人带来了问题,但它确实允许设置相对较短的连接超时,因为如果服务器完全不可用,为什么还要等待呢?然而,您仍然可以将请求超时设置得相当长,以防服务的预期响应时间难以预测。
一般来说,对于生产设置,CURLOPT_CONNECTION_TIMEOUT 应小于 5 秒,并且 CURLOPT_TIMEOUT 应尽可能低(不会导致您定期删除请求)。
除了接受的答案。
根据源代码连接设置:如果两者都设置,则使用最严格的设置。但仅限于连接阶段。
/* if a timeout is set, use the most restrictive one */
if(data->set.timeout > 0)
timeout_set |= 1;
if(duringconnect && (data->set.connecttimeout > 0))
timeout_set |= 2;
switch(timeout_set) {
//...
case 3:
if(data->set.timeout < data->set.connecttimeout)
timeout_ms = data->set.timeout;
else
timeout_ms = data->set.connecttimeout;
break;
CURLOPT_TIMEOUT
是否包含
CURLOPT_CONNECTTIMEOUT
的人;我会提醒您,libcurl 支持超过 23 种不同的操作系统,包括 DOS。互联网连接极其复杂(代理、DNS 解析、IP 连接、IP 接受、SSH/SSL 握手、通过 HTTP 等特定协议进行实际数据传输),并且 libcurl 可能并不总是能够准确满足请求的超时。
经验法则是你应该设置
CURLOPT_TIMEOUT
>=
CURLOPT_CONNECTTIMEOUT
因为这是手册所说的并且 libcurl 会尽力遵守。通常非常准确。但在某些平台或边缘情况下,您很容易遇到实际超时为
CURLOPT_TIMEOUT
+
CURLOPT_CONNECTTIMEOUT
的情况;或者哎呀,我什至遇到了所有超时都被忽略的情况,因为对于连接过程中的特定步骤,所涉及的操作系统/框架不要求超时值,并且不会将控制权返回给 libcurl;这超出了 libcurl 的控制范围。