当我尝试将PHP的cURL方法用于某些URL时,它会超时。当我使用命令行作为相同的URL时,它工作得很好。
我正在使用AWS,并且有一个运行来自yum的php-55 apache库的t2.medium框。
这是我的PHP代码:
function curl($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36');
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept-Language: en-us'
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
$fh = fopen('/home/ec2-user/curllog', 'w');
curl_setopt($ch, CURLOPT_STDERR, $fh);
$a = curl_exec($ch);
curl_close($ch);
fclose($fh);
$headers = explode("\n",$a);
var_dump($headers);
var_dump($a);
exit;
return $result;
}
所以这里的调用很好:
curl('http://www.google.com');
这将返回谷歌主页的数据。
但是,我尝试了另一个网址:
curl('http://www.trulia.com/profile/agent-1391347/overview');
我在curllog中得到了这个:
[ec2-user@central Node]$ cat ../curllog
* Hostname was NOT found in DNS cache
* Trying 23.0.160.99...
* Connected to www.trulia.com (23.0.160.99) port 80 (#0)
> GET /profile/agent-1391347/overview HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36
Host: www.trulia.com
Accept: */*
Accept-Language: en-us
* Operation timed out after 10002 milliseconds with 0 bytes received
* Closing connection 0
如果我从命令行运行它:
curl -s www.trulia.com/profile/agent-1391347/overview
立即返回(1秒内)NO输出。这是预料之中的。但是当我运行时:
curl -sL www.trulia.com/profile/agent-1391347/overview
正确地返回页面,就像我想要的那样。
那么,我的卷发有什么问题?
PHP 5.5.20
这是我的phpinfo()中的cURL位:
curl
cURL support => enabled
cURL Information => 7.38.0
Age => 3
Features
AsynchDNS => Yes
CharConv => No
Debug => No
GSS-Negotiate => No
IDN => Yes
IPv6 => Yes
krb4 => No
Largefile => Yes
libz => Yes
NTLM => Yes
NTLMWB => Yes
SPNEGO => Yes
SSL => Yes
SSPI => No
TLS-SRP => No
Protocols => dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, ldaps, pop3, pop3s, rtsp, scp, sftp, smtp, smtps, telnet, tftp
Host => x86_64-redhat-linux-gnu
SSL Version => NSS/3.16.2 Basic ECC
ZLib Version => 1.2.7
libSSH Version => libssh2/1.4.2
答案 0 :(得分:8)
我检查了你的功能curl()
看起来很好。无需更改功能中的任何内容。您需要做的只是将URL原样作为参数传递,无需将HTTPS
更改为HTTP
curl('http://www.trulia.com/profile/agent-1391347/overview');
原因:
您已告诉curl
不要验证SSL
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
如果您需要任何解释,请告诉我。
答案 1 :(得分:5)
详细输出显示明确的超时问题:
- 操作在10002毫秒后收到0字节时超时
这表示您的网络设置存在问题。这些更难找到,这可以在你自己的一端(例如在web服务器或PHP可执行文件的上下文中)或另一端。两个地方都可以在一定范围内扩展,但是服务器接受这两个请求,即使它们具有不同的请求标头,因此更有可能这是与执行上下文相关的,这也是您通常描述它的方式。
检查有关通过PHP执行这些请求的安全性和其他网络层是否有任何限制。例如。如果您没有进入系统管理和故障排除,请尝试使用不同的服务器映像。根据您的问题中共享的内容,很难说明究竟是什么导致您的超时。
答案 2 :(得分:4)
尝试增加以下行中的超时值:
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
这些是非常短的超时值 - CURLOPT_TIMEOUT专门限制了整个执行时间,尝试给出更大的值:
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
答案 3 :(得分:3)
你有2个VARIABLES
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
第一个,CURLOPT_CONNECTTIMEOUT
是允许连接服务器的最长时间`
您可以通过将其设置为0
来禁用它。
那是
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
但如果你在生产环境中,它不是一个好方法,因为它永远不会超时。
现在CURLOPT_TIMEOUT
允许cURL函数执行的最大秒数。
将其设置为更高的值
curl_setopt($ch, CURLOPT_TIMEOUT, 20); // 20 Seconds.