curl exec让php卡住,关于curl:curl_exec导致PHP脚本停止执行任何操作

当我在一个特定的URL上运行curl时,该站点停止响应,并且不会生成错误,尽管我已经将错误报告设置为on。我试过将curl超时设置为低值,然后它会产生一个错误,所以我知道它不会超时。

我想知道的主要问题是,这怎么可能发生,我怎么知道为什么?

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

(http://api.factual.com/v2/tables/bi0eJZ/read?api_key=*apikey*&filters={"category":"Automotive","$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"

1";

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

您可以尝试设置不同的useragent;我们以前遇到过垃圾邮件问题,我们对不喜欢的useragent做了一些有趣的事情。

另外,发布API密钥可能不是一个好主意。

有一件事:江户十一〔0〕不会做你所期望的。基本上,它执行$output = (curl_exec($ch) or die("hhtrjrstjsrjt".curl_error($ch)));,因为它返回的是布尔值而不是字符串。相反,要么将错误检查移到下一行,要么像这样显式地对其进行分组:($output = curl_exec($ch)) or die("hhtrjrstjsrjt".curl_error($ch));。

ircmaxell,最让我困惑的是,它永远不会到达下一行,即使没有"或死"。将useragent更改为浏览器的useragent似乎也没有任何作用。

我也有同样的问题。不会抛出任何错误,脚本就会死掉。

你知道所有的echoEd号码吗?

我认为您的Web服务器(apache、php-fpm等)由于超时、内存限制等原因而停止执行脚本。请尝试从Web服务器的日志中检索信息。我真的认为答案隐藏在那里。

需要更多调试信息。尝试使用CLI中的wget,查看是否有相同的问题。尝试使用cli中的curl查看是否有相同的问题。

请执行以下操作:使用fsockopen连接到服务器,手动发送每个参数,并监听返回的结果。了解实际返回的内容以及服务器何时返回都非常有用。告诉我们结果以便我们能更好地帮助您

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

要修复错误,必须编辑php.ini文件。

为了显示开发模式中的错误,将error_reporting值更改为E_ALL。

然后你必须启用卷曲延伸。要在php.ini中启用它,必须取消对以下行的注释:

extension=php_curl.dll

一旦编辑了这些值,不要忘记重新启动Web服务器(apache或nginx)

我也同意我的同事,你应该使用json字符串。

从我的角度来看,代码应该是:

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;

编辑:

另一种方法是为事实API使用官方的PHP驱动程序:事实API的官方PHP驱动程序

它提供了一个带有curl调试输出和异常调试输出的调试模式。

谢谢您。我忘了给EDOCX1[0]打电话。

我以前处理过普通PHP中的curl调用。curl调用是curl类的一部分。正如其他用户所建议的,url_encode($url)函数将为这个特定类准备字符串。如果不运行此函数,则可以传入破坏处理程序的URL(例如,通过使用无效字符或URL语法)。

除此之外,似乎您正试图将JSON对象直接传递到页面的URL中。我不认为在这样的curl调用中使用JSON包是最佳实践。如果这正是您要做的,请参见本页:如何从终端/commandline发布带有curl的JSON数据以测试SpringRest?

您的URL不是url_编码的,因为curl是一个外部应用程序转义是必需的。您的浏览器将自动对url_编码参数,但是您可能正在破坏服务器上的curl,它正在停止。

尝试更改:

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

但是我有个问题,你的电话对吗?Literal"$loc"的键是正确的吗?

更新以消除对所有单引号不支持变量替换的内容进行反斜杠操作的需要,并允许双引号不转义它们。

在我的例子中,curl失败是由于宿主提供者用liteSpeed替换了apache,liteSpeed在curl请求期间终止了进程。

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

我们聊了很久,我确信他们的服务器确实坏了(最终)。

为了让其他可能有类似或相关问题的人更清楚地了解这一点:我的PHP脚本正在运行,并且没有任何错误被记录到PHP中,因为整个PHP进程,包括错误记录器都被Web服务器终止。

为了将来的利益:

将查询参数的urlencode用作筛选参数包含许多对URL不安全/无效的字符

使用curl_getinfo()查看有关http代码和其他有用信息。

此代码仅供测试,请根据我的代码修改您的代码

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

?>

对于那些在家里跟着我们的人……如果你能解释你改变了什么以及为什么改变了它,那就太好了:)正如你可能注意到的那样-像这样的问题会在网站上停留很长一段时间,并且会被其他人发现,可能几个月后,他们也有类似的问题,并且想从中学习:)谢谢。

另外,使用双引号也可以实现这一点吗?我确信卷轴护腕适用于PHP中的变量。URL中的参数是否应进行urlencoded?

事实上,脚本完全停止执行任何操作,您可以在这里找到它:

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

摘录:

set_time_limit()函数和配置指令max_execution_time只影响脚本本身的执行时间。在确定脚本运行的最长时间时,不包括在脚本执行之外发生的任何活动上花费的时间,例如使用System()的系统调用、流操作、数据库查询等。在测量的时间是真实的窗口中,情况并非如此。

所以基本上,curl会阻塞所有的PHP脚本,基本上唯一实际运行的就是curl,所以如果它永远阻塞,你的站点将不会响应,这就是为什么你需要使用超时的原因…

至于如何避免它,只需使用超时…

如果php-curl没有在主机系统上使用curl,这通常是正确的,基本上是做一个非常花哨的exec("curl ...."),如果curl停止用户输入,php将只等待并等待它,不管您将超时设置为多长时间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值