curl_exec заставляет php-скрипт перестать что-либо делать - PullRequest
14 голосов
/ 14 февраля 2011

Когда я запускаю curl для определенного URL-адреса, сайт перестает отвечать и не генерирует ошибку, несмотря на то, что я установил функцию отчетов об ошибках на.Я попытался установить тайм-ауты завитков на низкие значения, и он выдает ошибку, поэтому я знаю, что время не истекло.

Главное, что я хочу знать, как это могло произойти и какможно узнать почему?

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 "\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;

Ответы [ 7 ]

3 голосов
/ 18 июля 2016

Похоже, у вас есть ошибки в файле конфигурации 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;

РЕДАКТИРОВАТЬ:

Другим подходом может быть использование Официального драйвера PHP для Factual API: Официальный драйвер PHP для Factual API

Он обеспечивает Режим отладки с выводом отладки cURL и выводом отладки Exception .

2 голосов
/ 18 июля 2016

Я работал с CURL-вызовами из vanilla PHP раньше.Вызов CURL является частью класса curl.Как и предполагали другие пользователи, функция url_encode($url) подготовит строку для использования этим конкретным классом.Если вы не запустите это, то можете передать URL-адреса, которые могут нарушить работу обработчиков (например, из-за недопустимых символов или синтаксиса URL).

Кроме того, кажется, что вы пытаетесь передать JSONОбъект прямо в URL страницы.Я не верю, что лучше всего работать с пакетами JSON при таком вызове curl.Если это то, что вы хотите сделать, см. Эту страницу: Как отправить данные JSON с помощью Curl из терминала / командной строки в Test Spring REST?

2 голосов
/ 18 июля 2016

Ваш URL не закодирован как url_en, так как CURL является внешним приложением, для которого необходимо экранирование, ваш браузер автоматически будет вводить параметры URL-адреса url_encode в 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);

Однако у меня есть вопрос, правильный ли ваш звонок? ключ литерлала "$ loc" это правильно?

Обновлен, чтобы убрать необходимость обратной косой черты во всех одинарных кавычках, не поддерживает замену переменных и разрешит двойные кавычки, не экранируя их

2 голосов
/ 18 июля 2016

В моем случае сбой скручивания произошел из-за того, что провайдер хостинга заменил Apache на Litespeed, а litespeed завершил процесс во время запроса скручивания.это происходило из-за того, что lsphp прерывался каждый раз по 30 секунд.

У нас был долгий разговор, и я убедил их, что их сервер действительно сломан (в конце концов).для других людей, у которых может быть похожая или связанная проблема:
Мой PHP-скрипт выполнялся, и в PHP не регистрировалось никаких ошибок, потому что весь процесс PHP, включая регистратор ошибок, прерывался веб-сервером.

1 голос
/ 19 июля 2016

Для будущей выгоды:

  1. Используйте urlencode для параметров запроса в качестве параметра фильтров. содержит много символов, которые не являются безопасными / действительными для URL

  2. Используйте curl_getinfo () для просмотра информации о http_code и другая полезная информация.

1 голос
/ 05 мая 2011

этот код только для тестирования, просто измените ваш код в соответствии с моим

<?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;
?>
0 голосов
/ 20 июля 2016

тот факт, что скрипт вообще ничего не делает, вы можете найти здесь:

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

выдержка:

Функция set_time_limit () и директива конфигурации max_execution_time влияют только на время выполнения самого скрипта. Любое время, потраченное на действия, которые происходят вне выполнения сценария, такие как системные вызовы с использованием system (), потоковые операции, запросы к базе данных и т. Д., Не учитывается при определении максимального времени выполнения сценария. Это не так в Windows, где измеренное время реально.

В общем, curl блокирует весь скрипт php, и фактически единственное, что на самом деле работает, это curl, поэтому, если он блокируется навсегда, ваш сайт не будет отвечать, поэтому вам нужно использовать таймауты ...

а как этого избежать, просто используйте таймауты ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...