¿File_get_contents () tiene una configuración de tiempo de espera?


152

Estoy llamando a una serie de enlaces usando el file_get_contents()método en un bucle. Cada enlace puede tardar más de 15 minutos en procesarse. Ahora, me preocupa si PHP file_get_contents()tiene un período de tiempo de espera.

En caso afirmativo, finalizará con una llamada y pasará al siguiente enlace. No quiero llamar al siguiente enlace sin que finalice el anterior.

Entonces, por favor dígame si file_get_contents()tiene un tiempo de espera. El archivo que contiene file_get_contents()se establece set_time_limit()en cero (ilimitado).



Experimenté el mismo comportamiento (tiempo de espera al consultar URL en el mismo "servidor") dentro de un proyecto PHP de Visual Studio que usa las herramientas PHP para extensiones de Visual Studio. Más información aquí .
Uwe Keim

Esto sucede también cuando se utiliza el servidor PHP incorporado para consultar una URL en el mismo sitio web , porque es un servidor web de subproceso único.
Uwe Keim

Respuestas:


298

El tiempo de espera predeterminado se define mediante default_socket_timeoutla configuración inicial , que es de 60 segundos. También puedes cambiarlo sobre la marcha:

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

Otra forma de establecer un tiempo de espera sería utilizarlo stream_context_createpara establecer el tiempo de espera como opciones de contexto HTTP del envoltorio de flujo HTTP en uso:

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

echo file_get_contents('http://example.com/', false, $ctx);

8
¿Puedes dar información sobre cómo configurar el tiempo de espera para la URL https?
Vinay

11
esto no funciona perfectamente, si su valor es 1200, en realidad es 2400. Solo lo pruebo.
TomSawyer

15
default_socket_timeout, stream_set_timeout y stream_context_create timeout son todos los tiempos de espera de cada línea de lectura / escritura, no todo el tiempo de espera de conexión.
Diyism

32

Como mencionó @diyism, " default_socket_timeout, stream_set_timeout y stream_context_create timeout son todos los tiempos de espera de cada línea de lectura / escritura, no todo el tiempo de conexión " . Y la respuesta principal de @stewe me ha fallado.

Como alternativa al uso file_get_contents, siempre puede usar curlcon un tiempo de espera.

Así que aquí hay un código de trabajo que funciona para llamar a enlaces.

$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
Esta respuesta ofrece otro enfoque para controlar el tiempo de espera de conexión (usando en fsockopenlugar de curl): stackoverflow.com/a/3690321/1869825
stevo

2
debes establecer CURLOPT_CONNECTTIMEOUT y CURLOPT_TIMEOUT en curl. Ver stackoverflow.com/a/27776164/1863432
bhelm

2
No es una respuesta válida, la pregunta es para "file_get_contents". La respuesta es excelente pero inapropiada.
e-info128

8

¡Si! Al pasar un contexto de flujo en el tercer parámetro:

Aquí con un tiempo de espera de 1s :

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

Fuente en la sección de comentarios de https://www.php.net/manual/en/function.file-get-contents.php

Opciones de contexto HTTP :

method
header
user_agent
content
request_fulluri
follow_location
max_redirects
protocol_version
timeout

Otros contextos: https://www.php.net/manual/en/context.php


1
La respuesta con 286 representantes no funcionó, pero la suya sí :)
VE7JRO

El tiempo de espera especificado stream_context_createsolo funciona para el tiempo de espera de conexión. Si el servidor responde (envía algunos datos) dentro del tiempo de espera determinado, pero tarda una eternidad en enviar el resto de su carga útil, este tiempo de espera no interrumpe la transferencia lenta.
z80crew

6

Vale la pena señalar que si cambia default_socket_timeout sobre la marcha, podría ser útil restaurar su valor después de su llamada 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
pero sabes que ini_set no establece las cosas permanentemente, ¿verdad? así que básicamente la mitad de tu script es inútil
Flash Thunder

2
@FlashThunder No si hay otra llamada a file_get_contents más adelante en el código que requiere el tiempo de espera anterior. Restaurar la configuración modificada sobre la marcha para un bit específico de código después de que ese código se haya ejecutado es generalmente una buena práctica.
Leigh Bicknell

1
@FlashThunder es una buena práctica restaurar el valor de socket_timeout después de una llamada para que las llamadas posteriores a la misma función en la misma ejecución del script utilicen la configuración global.
Pascal Roget

1

Para mí trabajo cuando cambio mi php.ini en mi host:

; Default timeout for socket based streams (seconds)
default_socket_timeout = 300
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.