Curl_exec заставляет PHP скрипт прекратить делать что-либо

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

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

URL-адрес, который я пытаюсь получить, - это вызов фактического api, и URL-адрес, который я использую здесь

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

Работает, когда вы кладете его в браузер. Php script работает по назначению, если вы измените широту и долготу практически на любые другие значения.

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;

Ответ 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;

EDIT:

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

Он обеспечивает режим отладки с cugl отладочный вывод и Исходный отладочный вывод.

Ответ 2

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

Настройки php.ini не исправили это, так как lsphp каждый раз заканчивался на 30 секунд.

У нас был длинный чат, и я убедил их, что их сервер был сломан (в конце концов).

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

Ответ 3

Ваш url не url_encoded, так как CURL - это внешнее приложение, требующее вашего браузера автоматически указывать параметры url_encode на URL-странице, однако вы можете ломать завиток на сервере и останавливаться.

Попробуйте изменить это:

$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" является правильным?

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

Ответ 4

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

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

Ответ 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;
?>

Ответ 6

В будущем:

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

  • Используйте curl_getinfo(), чтобы просмотреть информацию о http_code и другая полезная информация.

Ответ 7

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

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

выдержка:

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

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

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