open file_get_contents example ejemplos php

php - example - file_get_contents()



PHP file_get_contents muy lento cuando se usa la URL completa (9)

Nota: Esto se ha corregido en PHP 5.6.14. A Connection: close header se enviará automáticamente incluso para solicitudes HTTP / 1.0. Ver commit 4b1dff6 .

Me costó trabajo averiguar la causa de la lentitud de los scripts file_get_contents.

Al analizarlo con Wireshark, el problema (en mi caso y probablemente también el tuyo) fue que el servidor web remoto NO CERRÓ LA CONEXIÓN TCP HASTA 15 SEGUNDOS (es decir, "keep-alive").

De hecho, file_get_contents no envía un encabezado HTTP de "conexión", por lo que el servidor web remoto considera de manera predeterminada que se trata de una conexión keep-alive y no cierra la transmisión TCP hasta 15 segundos (puede no ser un valor estándar, depende en el servidor conf).

Un navegador normal consideraría que la página está completamente cargada si la longitud de la carga útil HTTP alcanza la longitud especificada en el encabezado HTTP Content-Length de la respuesta. File_get_contents no hace esto y es una pena.

SOLUCIÓN

SO, si quieres saber la solución, aquí está:

$context = stream_context_create(array(''http'' => array(''header''=>''Connection: close/r/n''))); file_get_contents("http://www.something.com/somepage.html",false,$context);

La cuestión es simplemente decirle al servidor web remoto que cierre la conexión cuando se complete la descarga , ya que file_get_contents no es lo suficientemente inteligente como para hacerlo solo con el encabezado HTTP Content-Length de respuesta.

Estoy trabajando con un script (que no creé originalmente) que genera un archivo pdf desde una página HTML. El problema es que ahora lleva mucho tiempo, como 1-2 minutos, procesar. Supuestamente esto funcionaba bien originalmente, pero se ha ralentizado en las últimas semanas.

El script llama a file_get_contents en un script php, que luego genera el resultado en un archivo HTML en el servidor y ejecuta la aplicación del generador de archivos PDF en ese archivo.

Parece que reduje el problema al llamado file_get_contents en una url completa, en lugar de una ruta local.

Cuando uso

$content = file_get_contents(''test.txt'');

procesa casi instantáneamente. Sin embargo, si utilizo la URL completa

$content = file_get_contents(''http://example.com/test.txt'');

toma de 30 a 90 segundos procesarlo.

No se limita a nuestro servidor, es lento cuando se accede a una url externa, como http://www.google.com . Creo que el script llama a la url completa porque hay variables de cadena de consulta que son necesarias y que no funcionan si llama al archivo localmente.

También probé fopen , readfile y curl , y todos fueron similarmente lentos. ¿Alguna idea sobre dónde buscar para solucionar esto?


¿Puedes intentar recuperar esa url, en el servidor, desde la línea de comandos? curl o wget vienen a la mente. Si aquellos recuperan la URL a una velocidad normal, entonces no es un problema de red y probablemente algo en la configuración de apache / php.


A veces, es porque el DNS es demasiado lento en su servidor, intente esto:

reemplazar

echo file_get_contents(''http://www.google.com'');

como

$context=stream_context_create(array(''http'' => array(''header''=>"Host: www.google.com/r/n"))); echo file_get_contents(''http://74.125.71.103'', false, $context);


Lo que también consideraría con Curl es que puede "enhebrar" las solicitudes. Esto me ha ayudado inmensamente ya que no tengo acceso a una versión de PHP que permita enhebrar en este momento.

Por ejemplo, obtenía 7 imágenes de un servidor remoto usando file_get_contents y tardaba entre 2 y 5 segundos por solicitud. Solo este proceso estaba agregando 30 segundos o algo al proceso, mientras el usuario esperaba que se generara el PDF.

Esto literalmente redujo el tiempo a aproximadamente 1 imagen. Otro ejemplo, verifico 36 URL en el tiempo que tomó antes para hacer una. Creo que entiendes el punto. :-)

$timeout = 30; $retTxfr = 1; $user = ''''; $pass = ''''; $master = curl_multi_init(); $node_count = count($curlList); $keys = array("url"); for ($i = 0; $i < $node_count; $i++) { foreach ($keys as $key) { if (empty($curlList[$i][$key])) continue; $ch[$i][$key] = curl_init($curlList[$i][$key]); curl_setopt($ch[$i][$key], CURLOPT_TIMEOUT, $timeout); // -- timeout after X seconds curl_setopt($ch[$i][$key], CURLOPT_RETURNTRANSFER, $retTxfr); curl_setopt($ch[$i][$key], CURLOPT_HTTPAUTH, CURLAUTH_ANY); curl_setopt($ch[$i][$key], CURLOPT_USERPWD, "{$user}:{$pass}"); curl_setopt($ch[$i][$key], CURLOPT_RETURNTRANSFER, true); curl_multi_add_handle($master, $ch[$i][$key]); } } // -- get all requests at once, finish when done or timeout met -- do { curl_multi_exec($master, $running); } while ($running > 0);

Luego revise los resultados:

if ((int)curl_getinfo($ch[$i][$key], CURLINFO_HTTP_CODE) > 399 || empty($results[$i][$key])) { unset($results[$i][$key]); } else { $results[$i]["options"] = $curlList[$i]["options"]; } curl_multi_remove_handle($master, $ch[$i][$key]); curl_close($ch[$i][$key]);

luego cierre el archivo:

curl_multi_close($master);


Sé que es una pregunta antigua, pero la encontré hoy y las respuestas no me funcionaron. No vi a nadie decir que las conexiones máximas por IP se pueden establecer en 1. De esa manera estás haciendo una solicitud de API y la API está haciendo otra solicitud porque utilizas la URL completa. Es por eso que cargar directamente desde el disco funciona. Para mí eso solucionó un problema:

if (strpos($file->url, env(''APP_URL'')) === 0) { $url = substr($file->url, strlen(env(''APP_URL''))); } else { $url = $file->url; } return file_get_contents($url);


Tengo una gran cantidad de datos pasados ​​por API, estoy usando file_get_contents para leer los datos, pero me tomó alrededor de 60 segundos . Sin embargo, usando la solución de KrisWebDev tomó alrededor de 25 segundos .

$context = stream_context_create(array(''https'' => array(''header''=>''Connection: close/r/n''))); file_get_contents($url,false,$context);


Tuve el mismo problema,

Lo único que funcionó para mí es establecer el tiempo de espera en $options array.

$options = array( ''http'' => array( ''header'' => implode($headers, "/r/n"), ''method'' => ''POST'', ''content'' => '''', ''timeout'' => .5 ), );


Utilizaría curl() para buscar contenido externo, ya que es mucho más rápido que el método file_get_contents . No estoy seguro si esto resolverá el problema, pero vale la pena intentarlo.

También tenga en cuenta que la velocidad de su servidor afectará el tiempo que lleva recuperar el archivo.

Aquí hay un ejemplo de uso:

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, ''http://example.com/test.txt''); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch);


$context = stream_context_create(array(''http'' => array(''header''=>''Connection: close/r/n''))); $string = file_get_contents("http://localhost/testcall/request.php",false,$context);

Tiempo: 50976 ms (tiempo de avaerage en total 5 intentos)

$ch = curl_init(); $timeout = 5; curl_setopt($ch, CURLOPT_URL, "http://localhost/testcall/request.php"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); echo $data = curl_exec($ch); curl_close($ch);

Tiempo: 46679 ms (tiempo de avaerage en total 5 intentos)

Nota: request.php se usa para obtener algunos datos de la base de datos mysql.