开发者

curl_exec causes php script to stop doing anything

When I run curl on a particular url, the site stops responding and doesn't generate an error, despite my having set error reporting to on. I've tried setting the curl timeouts to low values, and it generates an error then, so I know its not timing out.

The main thing I want to know is, how could that even happen, and how can I figure out why?

The url I'm trying to access is a call to the Factual api, and the url I'm using here

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

Works when you put it in a browser. The php script works as intended if you change the latitude and longitude to essentially any other values.

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;


It looks like you have some mistakes in your PHP configuration file.

To fix your errors you must edit your php.ini file.

For displaying errors in development mode, change the error_reporting value to E_ALL.

error_reporting=E_ALL

Then you have to enable the cURL extension. To enable it in your php.ini, yous have to uncomment the following line:

extension=php_curl.dll

Once you edited this values, don't forget to restart your webserver (Apache or Nginx)

Also I agree with my colleagues, you should url_encode your JSON string.

From my point of view the code should be:

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

EDIT:

Another approach could be to use the Official PHP driver for the Factual API: Official PHP driver for the Factual API

It provides a Debug Mode with a cURL Debug Output and a Exception Debug Output.


Your url is not url_encoded as CURL is an external application escaping is necessary your browser will auto url_encode params on the URL however you could be breaking curl on the server and it is halting.

Try changing 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}}";

to:

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

However i do have some question is your call correct? the key of literlal "$loc" is that correct?

Updated to remove the need to backslash everything single quotes don't support variable replace and will allow double quotes without escaping them


For future benefit:

  1. Use urlencode for query parameters as your filters parameter contains many characters that are not safe/valid for URLs

  2. Use curl_getinfo() to see information about http_code and other useful information.


In my case the curl failure was due to the fact that the hosting provider had replaced Apache with Litespeed, and litespeed was terminating the process during the curl request.

The php.ini settings didn't fix this as lsphp was getting terminated at 30 seconds every time.

We had a long chat, and I convinced them their server was actually broken (eventually).

To make this clearer for other people who might have a similar or related problem:
My PHP script was running, and no error was being logged in PHP because the entire PHP process, including the error logger was being terminated by the web server.


this code is just for testing, just modify your code according to mine

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


I have worked with CURL calls from vanilla PHP before. The CURL call is a part of the curl library. As other users have suggested, the url_encode($url) function would prepare the string for use by this particular class. If you do not run this, then you could pass in URLs which would break the handlers (e.g. by having invalid characters or URL syntax).

On top of this, it seems that you are trying to pass a JSON object directly into the URL of a page. I do not believe it is best practice to work with JSON packages in a curl call like this. If this is what you are looking to do, see this page: How do I POST JSON data with cURL?


the fact that the script stop doing anything at all you can found it in here:

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

excerpt:

The set_time_limit() function and the configuration directive max_execution_time only affect the execution time of the script itself. Any time spent on activity that happens outside the execution of the script such as system calls using system(), stream operations, database queries, etc. is not included when determining the maximum time that the script has been running. This is not true on Windows where the measured time is real.

so basically, curl blocks all the php script and basically the only thing that is actually running is curl, so if it blocks forever, your site will no respond, thats why you need to use timeouts...

as how to avoid it, just use timeouts...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜