Установка тайм-аута завивки в PHP

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

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

Ответ 1

См. документацию: 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 script self:

set_time_limit(0);// to infinity for example

Ответ 2

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

Ответ 3

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

Ответ 4

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

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

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

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

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

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

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

Ответ 5

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

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

Ответ 6

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

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

curl_setopt($ch, CURLOPT_TIMEOUT, 0);

В PHP снова вы должны удалить временные рамки или сам PHP (по истечении 30 секунд по умолчанию) убьет script по запросу 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);

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

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

Ответ 7

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