Есть ли у file_get_contents () время ожидания?

152

Я называю серию ссылок, используя file_get_contents()метод в цикле. Обработка каждой ссылки может занять более 15 минут. Теперь я беспокоюсь о том, file_get_contents()есть ли у PHP период ожидания?

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

Итак, скажите, пожалуйста, file_get_contents()есть ли период ожидания. Файл, который содержит значение file_get_contents(), установлен set_time_limit()на ноль (без ограничений).

Флора Клинтон
источник
Я испытал такое же поведение (время ожидания при запросе URL на том же «сервере») внутри проекта PHP Visual Studio, который использует PHP Tools для расширений Visual Studio. Больше информации здесь .
Уве Кейм
Это также происходит при использовании встроенного PHP-сервера для запроса URL-адреса на том же веб-сайте , поскольку он является однопоточным веб-сервером.
Уве Кейм

Ответы:

299

Время ожидания по умолчанию определяется default_socket_timeoutнастройкой ini , которая составляет 60 секунд. Вы также можете изменить его на лету:

ini_set('default_socket_timeout', 900); // 900 Seconds = 15 Minutes

Другой способ установить тайм - аут, будет использовать , stream_context_createчтобы установить тайм - аут в качестве опции контекста HTTP в HTTP поток обертки в использовании:

$ctx = stream_context_create(array('http'=>
    array(
        'timeout' => 1200,  //1200 Seconds is 20 Minutes
    )
));

echo file_get_contents('http://example.com/', false, $ctx);
stewe
источник
8
Можете ли вы дать информацию о том, как установить таймаут для https URL?
Vinay
11
эта вещь не работает идеально, если ваше значение 1200, на самом деле это 2400. Я просто протестирую это.
TomSawyer
15
default_socket_timeout, stream_set_timeout и stream_context_create timeout - это все тайм-аут каждой строки чтения / записи, а не весь тайм-аут соединения.
diyism
32

Как упомянул @diyism, « default_socket_timeout, stream_set_timeout и stream_context_create timeout - это все тайм-аут каждой строки чтения / записи, а не весь тайм-аут соединения ». И главный ответ @stewe меня не сработал.

В качестве альтернативы использованию file_get_contentsвы всегда можете использовать curlс таймаутом.

Итак, вот рабочий код, который работает для вызова ссылок.

$url='http://example.com/';
$ch=curl_init();
$timeout=5;

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);

$result=curl_exec($ch);
curl_close($ch);
echo $result;
Рэнделл
источник
1
Этот ответ дает другой подход к контролю времени ожидания подключения (используя fsockopenвместо curl): stackoverflow.com/a/3690321/1869825
stevo
2
Вы должны установить и CURLOPT_CONNECTTIMEOUT и CURLOPT_TIMEOUT в curl. См stackoverflow.com/a/27776164/1863432
bhelm
2
Не верный ответ, вопрос для "file_get_contents". Ответ велик, но неуместен.
e-info128
8

Да! Передавая контекст потока в третьем параметре:

Здесь с таймаутом 1 с :

file_get_contents("https://abcedef.com", 0, stream_context_create(["http"=>["timeout"=>1]]));

Источник в разделе комментариев https://www.php.net/manual/en/function.file-get-contents.php

Параметры HTTP-контекста :

method
header
user_agent
content
request_fulluri
follow_location
max_redirects
protocol_version
timeout

Другие контексты: https://www.php.net/manual/en/context.php

NVRM
источник
1
Ответ с 286 представителями не сработал, но ваш
сработал
Указанный тайм-аут stream_context_createработает только для тайм-аута соединения. Если сервер отвечает (отправляет некоторые данные) в течение заданного времени ожидания, но отправляет оставшуюся полезную нагрузку вечно, этот тайм-аут не прерывает медленную передачу.
z80crew
6

Стоит отметить, что при изменении default_socket_timeout на лету может быть полезно восстановить его значение после вызова file_get_contents :

$default_socket_timeout = ini_get('default_socket_timeout');
....
ini_set('default_socket_timeout', 10);
file_get_contents($url);
...
ini_set('default_socket_timeout', $default_socket_timeout);
Паскаль Роже
источник
1
но вы знаете, что ini_set не устанавливает вещи постоянно, верно? так что в основном 4 половины вашего сценария просто бесполезны
Flash Thunder
2
@FlashThunder Нет, если позже в коде есть другой вызов file_get_contents, который требует предыдущего тайм-аута. Восстановление настроек, измененных на лету для определенного фрагмента кода после его выполнения, обычно является хорошей практикой.
Ли Бикнелл
1
@FlashThunder - это хорошая практика для восстановления значения socket_timeout после вызова, чтобы последующие вызовы той же функции в том же исполнении скрипта использовали глобальные настройки.
Паскаль Роже
1

Для меня работа, когда я меняю свой php.ini на моем хосте:

; Default timeout for socket based streams (seconds)
default_socket_timeout = 300
Максимум
источник