【问题标题】:curl_exec causes php script to stop doing anythingcurl_exec 导致 php 脚本停止执行任何操作
【发布时间】:2011-06-27 01:58:38
【问题描述】:

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

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

我试图访问的 url 是对 Factual 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 "\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;

【问题讨论】:

  • 您可以尝试设置不同的用户代理;我们以前也遇到过垃圾邮件问题,并且我们用我们不喜欢的用户代理做了一些有趣的事情。
  • 另外,发布您的 API 密钥可能不是一个好主意
  • 一件事:$output = curl_exec($ch) or die("hhtrjrstjsrjt".curl_error($ch)); 不会做你所期望的。基本上,它正在执行$output = (curl_exec($ch) or die("hhtrjrstjsrjt".curl_error($ch)));,因为它返回的是布尔值而不是字符串。相反,要么将错误检查移到下一行,要么像这样显式分组:($output = curl_exec($ch)) or die("hhtrjrstjsrjt".curl_error($ch));
  • ircmaxell,让我感到困惑的主要事情是它永远不会进入下一行,即使没有“或死”。将用户代理更改为我的浏览器似乎也没有任何作用。
  • 我遇到了同样的问题。没有错误被抛出,脚本就死掉了。

标签: php curl


【解决方案1】:

您的 PHP 配置文件中似乎有一些错误。

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

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

error_reporting=E_ALL

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

extension=php_curl.dll

编辑此值后,不要忘记重新启动您的网络服务器(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;

编辑:

另一种方法是使用 Factual API 的官方 PHP 驱动程序: Official PHP driver for the Factual API

它提供了一个Debug Mode、一个cURL Debug Output和一个Exception Debug Output

【讨论】:

  • 谢谢。我忽略了取消注释extension=php_curl.dll
【解决方案2】:

您的 url 不是 url_encoded,因为 CURL 是一个外部应用程序转义是必要的,您的浏览器将在 URL 上自动 url_encode 参数,但是您可能会在服务器上破坏 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);

但是我确实有一些问题,您的电话是否正确?字面量 "$loc" 的键值对吗?

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

【讨论】:

    【解决方案3】:

    为了未来的利益:

    1. 使用urlencode 查询参数作为您的过滤器参数 包含许多对 URL 不安全/无效的字符

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

    【讨论】:

      【解决方案4】:

      在我的情况下,curl 失败是由于托管服务提供商已将 Apache 替换为 Litespeed,而 litespeed 在 curl 请求期间终止了该进程。

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

      我们聊了很久,我说服他们他们的服务器实际上(最终)坏了。

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

        • 对于我们这些在家里跟随的人.. 如果您能解释一下您所做的更改以及更改的原因,那就太好了 :) 您可能会注意到 - 像这样的问题留在网站上很长一段时间,可能几个月后被其他人发现,他们有类似的问题并想从中学习:) 谢谢。
        • 你也可以使用双引号来完成这项工作,我确信花括号是用于 php 中的变量的。 URL中的参数是否应该被URLencoded?
        【解决方案6】:

        我之前使用过来自原生 PHP 的 CURL 调用。 CURL 调用是curl 库的一部分。正如其他用户所建议的那样,url_encode($url) 函数将准备字符串以供该特定类使用。如果你不运行它,那么你可能会传入会破坏处理程序的 URL(例如,通过使用无效字符或 URL 语法)。

        除此之外,您似乎正试图将 JSON 对象直接传递到页面的 URL 中。我不认为在这样的 curl 调用中使用 JSON 包是最佳实践。如果这是您想要做的,请查看此页面:How do I POST JSON data with cURL?

        【讨论】:

          【解决方案7】:

          脚本停止做任何事情的事实你可以在这里找到它:

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

          摘录:

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

          所以基本上,curl 会阻止所有 php 脚本,并且基本上唯一实际运行的是 curl,所以如果它永远阻止,您的站点将不会响应,这就是您需要使用超时的原因...

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

          【讨论】:

          • 如果 PHP_CURL 没有在主机系统上使用 CURL,这通常是正确的将超时设置为。
          猜你喜欢
          • 1970-01-01
          • 2021-01-29
          • 1970-01-01
          • 1970-01-01
          • 2023-01-01
          • 2012-09-20
          • 1970-01-01
          • 1970-01-01
          • 2011-12-26
          相关资源
          最近更新 更多