2011-02-14 100 views
11

当我在特定的URL上运行curl时,尽管我已设置了错误报告,但站点停止响应并且不会生成错误。我试着将curl超时设置为低值,然后它会生成一个错误,所以我知道它不会超时。curl_exec导致php脚本停止任何事情

我想知道的主要事情是,这怎么可能发生,我怎么能找出原因?

我试图访问的URL是事实API的调用和URL,我在这里使用

http://api.factual.com/v2/tables/bi0eJZ/read?api_key=*apikey*&filters= { “类别”: “汽车”, “$ LOC”: {“$ within”:{“$ center”:[[41,-74],80467.2]}})

将它放入浏览器时有效。如果您将经纬度更改为基本上任何其他值,则php脚本将按预期工作。

error_reporting(E_ALL); 
ini_set('display_errors', '2'); 
$url="http://api.factual.com/v2/tables/bi0eJZ/read?api_key=*apikey*&filters={\"category\":\"Automotive\",\"\$loc\":{\"\$within\":{\"\$center\":[[41,-74],80467.2]}},\"website\":{\"\$blank\":false}}"; 
Echo "\n\n1"; 

$ch = curl_init($url); 
Echo 2; 
curl_setopt($ch, CURLOPT_HEADER, 0); 
Echo 3; 
curl_setopt($ch, CURLOPT_POST, 1); 
Echo 4; 
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,15); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_TIMEOUT,30); 
Echo 5; 
$output = curl_exec($ch) or die("hhtrjrstjsrjt".curl_error($ch)); 
Echo 6; 
curl_close($ch); 
Echo "out: ".$output; 
+6

你可以尝试设置一个不同的useragent;我们之前有过垃圾邮件问题,而且我们使用我们不喜欢的垃圾邮件进行有趣的事情。 – 2011-02-14 17:41:51

+2

另外,发布你的API密钥可能不是一个好主意 – DFectuoso 2011-02-14 17:48:11

+3

有一件事:``output = curl_exec($ ch)或die(“hhtrjrstjsrjt”.curl_error($ ch));`不会达到你所期望的。基本上,它正在执行`$ output =(curl_exec($ ch)或die(“hhtrjrstjsrjt”.curl_error($ ch)));`因为它返回一个布尔值而不是字符串。相反,要么将错误检查移动到下一行,要么将其显式分组,如下所示:`($ output = curl_exec($ ch))或die(“hhtrjrstjsrjt”.curl_error($ ch));` – ircmaxell 2011-02-14 17:48:54

回答

1

这个代码只是为了测试,只需修改根据矿山

<?php 

$useragent = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) 
Chrome/8.0.552.224: Safari/534.10'; // notice this 
$url="http://api.factual.com/v2/tables/bi0eJZ/read?api_key=*apikey*&filters={\"category\":\"Automotive\",\"\$loc\":{\"\$within\":{\"\$center\":[[41,-74],80467.2]}},\"website\":{\"\$blank\":false}}"; 
$ch = curl_init(); // notice this 

curl_setopt($ch, CURLOPT_URL, $url); // notice this 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 

curl_setopt($ch, CURLOPT_USERAGENT, $useragent); 




$contents = curl_exec($ch); 
echo $contents; 
?> 
2

在我的情况下卷曲故障是由于该托管服务提供商已经取代阿帕奇用的Litespeed其实你的代码, litespeed在curl请求期间终止了该进程。

php.ini设置没有解决这个问题,因为lsphp每次都在30秒终止。

我们进行了长时间的聊天,我确信他们的服务器实际上已经损坏(最终)。

要对谁可能有类似或相关的问题其他人更清楚:
我的PHP脚本运行,并在PHP中被记录没有错误,因为整个PHP程序,包括错误记录器是由Web服务器终止。

2

由于CURL是一个外部应用程序,因此您的网址并不是url_encoded,因此您的浏览器会自动在网址上使用url_encode params,但是您可能会在服务器上发生卷曲并停止运行。

尝试改变这一点:

$url="http://api.factual.com/v2/tables/bi0eJZ/read?api_key=*apikey*&filters={\"category\":\"Automotive\",\"\$loc\":{\"\$within\":{\"\$center\":[[41,-74],80467.2]}},\"website\":{\"\$blank\":false}}"; 

到:

$url_filters = '{"category":"Automotive","$loc":{"$within":{"$center":[[41,-74],80467.2]}},"website":{"$blank":false}}'; 

$url="http://api.factual.com/v2/tables/bi0eJZ/read?api_key=*apikey*&filters=".urlencode($url_filters); 

然而,我有一些问题是你的电话是否正确? literlal“$ loc”的关键是否正确?

更新,删除需要反斜杠一切单引号不支持变量替换,将允许双引号没有逃脱他们

2

我曾与香草PHP之前卷曲电话工作。 CURL呼叫是curl类的一部分。正如其他用户所建议的那样,url_encode($url)函数会准备供该特定类使用的字符串。如果您不运行此操作,那么您可以传递会破坏处理程序的URL(例如,使用无效字符或URL语法)。

最重要的是,您似乎试图将JSON对象直接传递到页面的URL中。我不认为最好的做法是像这样用curl调用JSON包。如果这是你正在做的,看到这个页面:How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?

3

看起来你在你的PHP配置文件中有一些错误。

要解决您的错误,您必须编辑您的php.ini文件。

若要在开发模式下显示错误,请将error_reporting的值更改为E_ALL

error_reporting=E_ALL 

然后您必须启用cURL扩展。 要启用它在你的php.ini,你要跟不得不取消注释以下行:

extension=php_curl.dll 

一旦你编辑这个值,别忘了重新启动web服务器(Apache或Nginx的)

而且我同意我的同事,你应该url_encode你的JSON字符串。

从我的观点来看,代码应该是:

<?php 
ini_set('display_errors', '1'); 
error_reporting(E_ALL); 

$apiKey = '*apikey*'; 
$filters = '{"category":"Automotive","$loc":{"$within":{"$center":[[41,-74],80467.2]}},"website":{"$blank":false}}'; 
$params = '?api_key=' . $apiKey . '&filters=' . url_encode($filters); 

$url = 'http://api.factual.com/v2/tables/bi0eJZ/read'; 
$url .= $params; 

$ch = curl_init($url); 
curl_setopt($ch, CURLOPT_HEADER, 0); 
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_TIMEOUT, 30); 
$output = curl_exec($ch) or die("cURL Error" . curl_error($ch)); 
curl_close($ch); 

echo "out: " . $output; 

编辑:

另一种方法可以是使用PHP官方驱动程序用于事实API: Official PHP driver for the Factual API

它提供了一个Debug ModecURL Debug OutputException Debug Output

1

对于未来的好处:

  1. 使用urlencode查询参数的过滤器参数 包含许多字符是不是安全/有效的URL

  2. 使用curl_getinfo()看到有关HTTP_CODE和 信息其他有用的信息。

0

的事实,脚本停止所有做任何事情,你可以发现它在这里:

http://php.net/manual/en/function.set-time-limit.php

摘录:

的set_time_limit()函数的功能和配置指令的max_execution_time只影响脚本本身的执行时间。在确定脚本运行的最长时间时,不包括使用system()系统调用,流操作,数据库查询等脚本执行之外发生的任何活动时间。在测量时间是真实的Windows上,这不是事实。

所以基本上,卷曲阻止所有的PHP脚本,基本上是实际运行的唯一的事情是卷曲的,所以如果它永远块,你的网站会没有反应,这就是为什么你需要使用超时......

作为如何避免它,只需使用超时...