Чи має файл_get_contents () встановлення тайм-ауту?


152

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

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

Отже, будь ласка, скажіть, чи file_get_contents()є період очікування. Файл, який містить file_get_contents(), встановлений set_time_limit()на нуль (необмежений).



Я відчував таку ж поведінку (тайм-аут при запиті URL-адреси на тому самому «сервері») в PHP-проекті Visual Studio, який використовує інструменти PHP для розширень Visual Studio. Більше інформації тут .
Уве Кеїм

Це трапляється і при використанні вбудованого сервера PHP для запиту URL-адреси на одному веб-сайті , оскільки це однопотоковий веб-сервер.
Уве Кеїм

Відповіді:


298

Час очікування за замовчуванням визначається default_socket_timeoutini-налаштуванням , яке становить 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-адреси?
Винай

11
ця річ працює не ідеально, якщо у вас значення 1200, то насправді це 2400. Я просто тестую її.
TomSawyer

15
time_socket_timeout, stream_set_timeout та time_out stream_context_create - це час очікування кожного читання рядка / запису рядка, а не весь час очікування з'єднання.
диїзм

32

Як зазначав @diyism, " time_socket_timeout, stream_set_timeout та time_outtect_create timeout - це час очікування кожного читання рядка / запису рядка, а не весь час очікування з'єднання ".

В якості альтернативи використанню 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
Стево

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.