CURL php代码返回http_code = 0并从服务器消息中清空回复

时间:2013-09-12 20:31:43

标签: php curl

我在多个站点/服务器上运行相同的代码。 2天前,代码开始在其中一台服务器上返回http_code = 0和错误消息“来自服务器的空回复”。

任何人都可以了解为什么特定服务器有一天会工作,然后不工作下一个?我已经向ISP提交了一张解释该问题的票,但他们似乎无法找到问题(还)。

我想这个问题确实是,在服务器上会发生什么/可能会改变以阻止它工作?

有趣的是,我引用的网址没有触及返回错误的服务器。如果我将url更改为指向不存在的内容,则会返回相同的错误。因此,服务器似乎拒绝了总共CURL POST引用。我目前有其他CURL脚本可以访问仍然有效的问题站点,但是它们没有POST选项。

这个问题肯定与此服务器上的CURL POST请求有关,并且它们几乎被立即拒绝。

在有问题的服务器上我有15个以上的独立帐户,每个帐户都会返回相同的结果,所以我不认为我已经更改了任何内容,因为我知道我还没有对所有网站进行任何批量更改问题出现了。在我在其他地方托管的其他6个网站中,一切都运行良好,代码完全相同。

我已经尝试过各种组合/更改来自我阅读过的帖子,但没有什么真正有所作为,工作网站仍在工作,非工作网站仍然没有。

function sendWSRequest($url, $xml) {

//  $headers[] = 'Content-Type: application/xml; charset=utf-8';
    $headers[] = 'Content-Type: text/xml; charset=utf-8';
    $headers[] = 'Content-Length: ' . strlen($xml);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HEADER, true);
//  curl_setopt($ch, CURLINFO_HEADER_OUT, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
//  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);

    $result = curl_exec($ch);
    if($result===false) {
        print 'error with curl - '.curl_error($ch).'<br />';
    }

    $info = curl_getinfo($ch);

    curl_close($ch);

    return $result;
}

非常感谢任何帮助。

EDIT 总结一下,基于进一步的调查,当脚本出错时,服务器访问日志中没有任何注册事项。因此,在授予/记录访问权限之前,似乎拒绝了包含POST选项的CURL请求...

干杯

Greg J

3 个答案:

答案 0 :(得分:5)

我知道这是一个老线程,但我找到了一个可以让别人头疼的解决方案:

我刚刚开始在GoDaddy托管的网站遇到这个确切的问题,该网站直到最近才开始工作。为了解决这个问题,我创建了一个HTML页面,其中的表单包含通过cURL在POST数据中提交的相同字段。

浏览器提交的HTML表单有效,而cURL POST导致Empty reply from server错误。所以我检查了浏览器提交的标题与cURL使用我的开发系统上的PHP apache_request_headers()函数提交的标题之间的区别,其中cURL和浏览器提交都有效。

我添加&#34; User-Agent&#34;我的浏览器提交到cURL POST的标题,问题网站按预期工作,而不是返回空回复:

CURLOPT_HTTPHEADER =>
      array("User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0")

我没有尝试其他/更简单的User-Agent标头,因为这个快速解决方案解决了我的问题。

答案 1 :(得分:2)

根据the PHP manual,上传应为 urlencoded

  

CURLOPT_POSTFIELDS在HTTP“POST”操作中发布的完整数据。   [...]此参数可以   作为urlencoded字符串传递,如'para1 = val1&amp; para2 = val2&amp; ...'或as   数组,字段名称为键,字段数据为值。 如果有价值   是一个数组,Content-Type标头将设置为   多部分/格式数据即可。从PHP 5.2.0开始,如果是文件,则值必须是数组   使用@前缀传递给此选项。从PHP 5.5.0开始,@   不推荐使用前缀,可以使用CURLFile发送文件。

所以你可以试试

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'xml=' . urlencode($xml));

看看会发生什么。或者,无论如何,从一个空的或非常简单的FIELD开始,看它是否至少到达目标服务器。

更新

我在测试机器上检查了此设置,可以正常工作。在这一点上,问题可能根本就不是PHP或cURL方面。您能否在最近几天申请该机器和网络上的软件/硬件更新列表?

否则,我会尝试捕获传出流量,以确定请求是否离开服务器(问题介于两者之间,例如配置错误的防火墙:因此我包含了“硬件”在更改列表中),或根本不离开服务器。在后一种情况下,罪魁祸首可能是:

  • 更新cURL库
  • 更新PHP cURL模块和/或PHP二进制文件
  • 更新“软件”防火墙规则
  • 更新辅助网络库(不太可能;它们应该是HTTP不可知的,不能区分POST,例如GET或HEAD)

答案 2 :(得分:0)

好的,事实证明,一个相当不情愿的主机重新编译了Apache2和PHP,它解决了这个问题。

主持人声称(他们对我的支持票证的开场陈述)在问题发生时没有对Apache2或PHP进行任何更新。

行为就是这样,甚至没有确认包含POST命令的CURL请求。从未到达目标网址。

非常感谢所有提出建议的人。特别是Isemi,他竭尽全力寻找解决方案。