Есть ли у 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);

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


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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.