Установка таймаута Curl в PHP - PullRequest
202 голосов
/ 06 апреля 2010

Я запускаю запрос curl для базы данных eXist через php. Набор данных очень большой, и, как следствие, базе данных постоянно требуется много времени для возврата XML-ответа. Чтобы это исправить, мы настроили запрос curl, который должен быть долгим.

$ch = curl_init();
$headers["Content-Length"] = strlen($postString);
$headers["User-Agent"] = "Curl/1.0";

curl_setopt($ch, CURLOPT_URL, $requestUrl);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'admin:');
curl_setopt($ch,CURLOPT_TIMEOUT,1000);
$response = curl_exec($ch);
curl_close($ch);

Однако запрос скручивания последовательно завершается до его завершения (<1000 при запросе через браузер). Кто-нибудь знает, это правильный способ установить таймауты в curl? </p>

Ответы [ 7 ]

308 голосов
/ 16 июня 2012

См. Документацию: http://www.php.net/manual/en/function.curl-setopt.php

CURLOPT_CONNECTTIMEOUT - количество секунд ожидания при попытке подключения. Используйте 0, чтобы ждать бесконечно.
CURLOPT_TIMEOUT - Максимальное количество секунд, в течение которых могут выполняться функции cURL.

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); 
curl_setopt($ch, CURLOPT_TIMEOUT, 400); //timeout in seconds

также не забудьте увеличить время выполнения скрипта php self:

set_time_limit(0);// to infinity for example
54 голосов
/ 06 апреля 2010

Хм, мне кажется, что CURLOPT_TIMEOUT определяет количество времени, которое разрешено выполнять любой функции cURL. Я думаю, что вы должны смотреть CURLOPT_CONNECTTIMEOUT вместо этого, так как это говорит cURL максимальное количество времени ожидания для завершения соединения.

26 голосов
/ 23 апреля 2012

Ваш код устанавливает время ожидания на 1000 секунд . Для миллисекунд используйте CURLOPT_TIMEOUT_MS.

25 голосов
/ 09 декабря 2013

Есть странность, которая может быть полезна для некоторых людей ... Из комментариев к документам PHP.

Если вы хотите, чтобы cURL превысил время ожидания менее чем за одну секунду, вы можете использовать CURLOPT_TIMEOUT_MS, хотя в «Unix-подобных системах» есть ошибка / «особенность», которая приводит к немедленному прекращению работы libcurl, если значение <1000 мс с ошибкой «Ошибка cURL (28): истекло время ожидания». Объяснение этого поведения: </p>

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

Что это означает для разработчиков PHP: «Вы не можете использовать эту функцию без предварительного тестирования, потому что вы не можете сказать, использует ли libcurl стандартный преобразователь имен системы (но вы можете быть уверены, что это так)»

Проблема заключается в том, что на (Li | U) nix, когда libcurl использует стандартный преобразователь имен, при разрешении имени вызывается SIGALRM, который, по мнению libcurl, является сигналом тайм-аута.

Решением является отключение сигналов с помощью CURLOPT_NOSIGNAL. Вот пример сценария, который запрашивает себя, вызывая 10-секундную задержку, чтобы вы могли проверить таймауты:

if (!isset($_GET['foo'])) {
    // Client
    $ch = curl_init('http://localhost/test/test_timeout.php?foo=bar');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200);
    $data = curl_exec($ch);
    $curl_errno = curl_errno($ch);
    $curl_error = curl_error($ch);
    curl_close($ch);

    if ($curl_errno > 0) {
        echo "cURL Error ($curl_errno): $curl_error\n";
    } else {
        echo "Data received: $data\n";
    }
} else {
    // Server
    sleep(10);
    echo "Done.";
}

С http://www.php.net/manual/en/function.curl-setopt.php#104597

9 голосов
/ 13 мая 2017

Вам необходимо убедиться в тайм-аутах между вами и файлом. В этом случае PHP и Curl.

Чтобы сообщить Curl, что он никогда не будет превышать тайм-аут, когда передача еще активна, вам нужно установить CURLOPT_TIMEOUT на 0 вместо 1000.

curl_setopt($ch, CURLOPT_TIMEOUT, 0);

В PHP, опять же, вы должны удалить временные ограничения или PHP сам по себе (через 30 секунд по умолчанию) уничтожит скрипт по запросу Curl. Уже одно это должно решить вашу проблему .
Кроме того, если вам требуется целостность данных, вы можете добавить уровень безопасности, используя ignore_user_abort:

# The maximum execution time, in seconds. If set to zero, no time limit is imposed.
set_time_limit(0);

# Make sure to keep alive the script when a client disconnect.
ignore_user_abort(true);

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

Отвечая на этот старый вопрос, потому что эта тема находится вверху поисковика и ищет CURL_TIMEOUT.

8 голосов
/ 06 апреля 2010

Вы не можете запустить запрос из браузера, он будет зависать в ожидании ответа от сервера, на котором выполняется запрос CURL. Вероятно, время ожидания браузера составляет 1-2 минуты, по умолчанию время ожидания сети.

Вам необходимо запустить его из командной строки / терминала.

3 голосов
/ 05 января 2014

Если вы используете PHP в качестве приложения fastCGI, то обязательно проверьте настройки тайм-аута fastCGI. См .: PHP curl put 500 error

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