PHP cURL方法在某些URL上超时,但命令行始终有效



当我尝试对某些URL使用PHP的cURL方法时,它会超时。当我对同一个URL使用命令行时,它运行得很好。

我使用的是AWS,并且有一个t2.medium盒子,它运行来自yum的php-55 apache库。

这是我的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');

这将返回谷歌主页的数据。

然而,我尝试了另一个URL:

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秒内),没有输出。这是意料之中的事。然而,当我运行这个:

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

我已经检查了你的函数curl(),看起来很好。无需更改函数中的任何内容。您需要做的只是按原样传递URL作为参数,无需将HTTPS更改为HTTP

curl('http://www.trulia.com/profile/agent-1391347/overview');

原因:

你已经告诉curl不要验证SSL

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

如果你需要任何解释,请告诉我。

详细输出显示一个清除超时问题:

  • 操作在10002毫秒后超时,收到0个字节

这表示您的网络设置出现问题。它们很难定位,可以在您自己的一端(例如,在Web服务器或PHP可执行文件的上下文中),也可以在另一端。在一定程度上,这两个地方都是可能的,但是服务器接受这两个请求,即使它们有不同的请求头,所以这更有可能是与执行上下文相关的,这也是你通常描述它的方式

检查在通过PHP执行这些请求时,安全层和其他网络层是否有任何限制。例如,如果您不太了解系统管理和故障排除,请尝试其他服务器映像。从你的问题中分享的内容来看,很难说是什么导致了你的超时。

尝试增加以下行中的超时值:

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);

您有2个变量

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);

第一个,CURLOPT_CONNECTTIMEOUT是允许连接到服务器的最大时间量`

您可以通过将其设置为0来禁用它。

那是

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);

但是,如果您在生产环境中,这不是一个好方法,因为它永远不会超时。

现在CURLOPT_TIMEOUT

来自PHP文档

允许cURL函数执行的最大秒数。

将其设置为某个更高的值

curl_setopt($ch, CURLOPT_TIMEOUT, 20); // 20 Seconds.

相关内容

最新更新