自从我将服务器从 PHP 5.3.x 升级到 PHP 5.5.3 以来,我遇到了 PHP Web 服务客户端的问题。
我有这个函数来计算 cURL 执行请求所需的时间:
function makeRequest($method, $uri) {
global $requests;
addTime("makeRequest");
$curl = curl_init($uri);
curl_setopt($curl, CURLOPT_HEADER , true );
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true );
curl_setopt($curl, CURLOPT_MAXREDIRS , 10 );
curl_setopt($curl, CURLOPT_CUSTOMREQUEST , $method);
//////////////////////////////
addTime("curl_exec");
$responseContent = curl_exec($curl);
remTime("curl_exec");
addTime("curl_getInfo");
$responseInfo = curl_getinfo($curl);
remTime("curl_getInfo");
array_push( $requests, var_export( $responseInfo, true ) );
remTime("makeRequest");
}
addTime
和 remTime
是记录 microtime(true)
以准确测量方法执行的函数。我还记录了 curl_getinfo
报告的不同时间)。见下文。我用一堆不同的 URI 尝试了它。这些是我的结果:
https://api1.mywebservice.com/methodCall
makeRequest
时间:0.402https://api2.mywebservice.com/methodCall
api2.mywebservice.com 被硬编码到机器的
%windir%\system32\drivers\etc\hosts
文件中为 127.0.0.1
所以它永远不应该为此访问 DNS 服务器makeRequest
时间:0.402https://localhost/methodCall
makeRequest
时间:0.403https://127.0.01/methodCall
makeRequest
时间:0.006服务器的DNS服务器距离只有5ms左右,但无论如何都应该缓存名称。
api2.mywebservice.com
获得相同时间的事实表明,这不是 DNS 服务器超时的问题,而是 cURL 内部腐烂的问题。我也试过
CURLOPT_RESOLVE
但没有效果:curl_setopt( $c, CURLOPT_RESOLVE, array("api1.mywebservice.com:443:127.0.01") );
为什么在最新(当然也是最好的)版本的 PHP 中,cURL 需要这么长时间才能检索到结果?
最佳答案
您的 libcurl 似乎是为使用它自己的名称解析器而不是系统名称解析器而构建的。在这种情况下,它根本不使用主机文件。
有3种可能的解决方案:
另外:来自 php.net 的 php 5.5.4 windows 二进制文件使用系统解析器进行 curl。它使用内部缓存(使用
CURLOPT_DNS_USE_GLOBAL_CACHE
时)和系统 DNS 缓存。我已经通过一些测试对其进行了检查。 A 还通过 curl 检查了名称解析的速度 - 它与 localhost 相同(对于写入主机文件的任何记录)。所以,我绝对相信这不是 PHP 问题:https://127.0.01/methodCall
必须是 https://127.0.0.1/methodCall
。在这种情况下,curl 总是返回 total_time = 0。 curl_getinfo($curl)
的所有字段,尤其是 "primary_ip"
。 关于Win32 上的 PHP 5.5.3 - cURL 需要 400 毫秒以上来解析所有域名,甚至是本地主机,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18888101/