0%

PHP调用curl设置CURLOPT_TIMEOUT_MS小于1秒时无效

今天使用php调用curl时碰到一个奇怪的问题,现象为当CURLOPT_TIMEOUT_MS小于1000时,直接返回错误

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

$ch = curl_init('https://nichijou.me/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200);
$data = curl_exec($ch);
$curl_errno = curl_errno($ch);
$curl_error = curl_error($ch);
curl_close($ch);

if ($curl_errno > 0) {
echo "cURL Error ($curl_errno): $curl_error\n";
} else {
echo "Data received: $data\n";
}

// cURL Error (28): Timeout was reached

翻了一下文档

https://www.php.net/manual/zh/function.curl-setopt.php

选项 value 设置为 备注
CURLOPT_TIMEOUT_MS 设置cURL允许执行的最长毫秒数。 如果 libcurl 编译时使用系统标准的名称解析器( standard system name resolver),那部分的连接仍旧使用以秒计的超时解决方案,最小超时时间还是一秒钟。 在 cURL 7.16.2 中被加入。从 PHP 5.2.3 起可使用。

查解决办法的时候发现鸟哥早在14年就描述过这个问题

http://www.laruence.com/2014/01/21/2939.html

解决这个问题的几种方式:

  1. 设置 curl_setopt($ch, CURLOPT_NOSIGNAL, 1);,但是会导致DNS解析不受控,万一DNS服务器出问题,可能会导致服务超时
  2. 升级libcurl版本到7.19及以上