2010-04-18 26 views
13

Actualmente estoy usando file_get_contents() para enviar datos GET a una gran variedad de sitios, pero después de la ejecución de la página me sale este error:alternativa más rápida a file_get_contents()

Fatal error: El tiempo máximo de ejecución de 30 segundos excedieron

Todo lo que realmente quiero que el script haga es comenzar a cargar la página web, y luego irse. Cada página web puede tardar hasta 5 minutos en cargarse por completo, y no es necesario que se cargue por completo.

Esto es lo que tengo actualmente:

 foreach($sites as $s) //Create one line to read from a wide array 
     { 
       file_get_contents($s['url']); // Send to the shells 
     } 

EDIT: Para aclarar cualquier confusión, este guión está siendo utilizado para iniciar scripts en otros servidores, que devuelven datos.

EDITAR: Estoy tratando de usar cURL para hacer el truco, estableciendo un tiempo de espera de un segundo para enviar los datos y luego detenerlos. Aquí está mi código:

 $ch = curl_init($s['url']); //load the urls 
     curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); //Only send the data, don't wait. 
     curl_exec($ch); //Execute 
     curl_close($ch); //Close it off. 

Tal vez he configurado la opción incorrecta. Estoy mirando algunos manuales mientras hablamos. Solo te estoy dando una actualización. Gracias a todos ustedes que me están ayudando hasta ahora.

EDITAR: Ah, encontró el problema. Estaba usando CURLOPT_CONNECTTIMEOUT en lugar de CURLOPT_TIMEOUT. Whoops.

Sin embargo, ahora, los scripts no se activan. Cada uno de ellos usa ignore_user_abort (TRUE); entonces no puedo entender el problema

Hah, rayar eso. Funciona ahora Muchas gracias a todos

+0

¿Usted ha intentado usar rizo? –

+0

No, no tengo experiencia con cURL. Quería hacerlo con algo con lo que al menos tengo un poco de experiencia. ¿Crees que debería eliminar esto con php e ir con cURL? – Rob

+0

¿qué hace exactamente la página web? ¿solo quieres que comience un script que debería ejecutarse solo, que no devuelve datos? –

Respuesta

6

Hay muchas formas de solucionar esto.

Puede usar cURL con sus funciones curl_multi_ * para ejecutar asincrónicamente las solicitudes.O use cURL de la manera común, pero usando 1 como límite de tiempo de espera, por lo que solicitará y devolverá el tiempo de espera, pero la solicitud se ejecutará.

Si no tiene instalado cURL, puede continuar usando file_get_contents pero realizando procesos de bifurcación (no tan genial, pero funciona) usando algo como ZendX_Console_Process_Unix para evitar la espera entre cada solicitud.

+0

Sí que lo vea en esto y jugar con él durante unos minutos – Rob

+0

intentado esto: \t \t \t $ ch = curl_init ($ s [ 'url']); // cargar las direcciones URL \t \t \t curl_setopt ($ ch, CURLOPT_CONNECTTIMEOUT, 1); // Solo envía los datos, no esperes. \t \t \t curl_exec ($ ch); // Ejecutar \t \t \t curl_close ($ ch); // Ciérralo Todavía está cargando todos ellos – Rob

+0

Lo siento, no tengo tiempo para probarlo. Es posible que desee probar los otros métodos. – Franco

2

Re su actualización que sólo tiene que gatillo la operación:

Usted podría tratar de usar file_get_contents con un tiempo de espera. Esto daría lugar a que se llamara a la secuencia de comandos remota, pero la conexión finalizara después de n segundos (por ejemplo, 1).

Si la secuencia de comandos remota está configurada para que continúe ejecutándose incluso si la conexión se interrumpe (en PHP sería ignore_user_abort), debería funcionar.

Pruébelo. Si no funciona, no te moverás aumentando tu time_limit o usando un ejecutable externo. Pero por lo que dices, solo tienes que hacer la solicitud, esto debería funcionar. Incluso podría intentar establecer el tiempo de espera en 0, pero no confiaría en eso.

De here:

<?php 
$ctx = stream_context_create(array(
    'http' => array(
     'timeout' => 1 
     ) 
    ) 
); 
file_get_contents("http://example.com/", 0, $ctx); 
?> 

Para ser justos, la respuesta de Chris ya incluye esta posibilidad: curl también tiene un interruptor de tiempo de espera.

+0

Bien, sé por qué la descarga lleva tanto tiempo, son las páginas que estoy cargando, tardan entre 30 segundos y 5 minutos en cargarse por completo. – Rob

1

no es file_get_contents() que consume tanto tiempo sino la conexión de red.
Considere no enviar datos GET a una matriz de sitios, pero cree un rss y permítales obtener datos RSS.

+0

+1, enfoque más seguro si hay un feed disponible. Pero eso dejará algunos sitios débiles de alimentación donde continúa bloqueando, lo que arreglaría el rizo. –

1

No entiendo completamente el significado detrás de su script. Pero aquí es lo que puede hacer:

  1. Con el fin de evitar el error fatal rápidamente que sólo puede añadir set_time_limit (120) al principio del archivo. Esto permitirá que la secuencia de comandos se ejecute durante 2 minutos. Por supuesto, puede usar cualquier número que desee y 0 para infinito.
  2. Si solo necesita llamar a la url y no le "importa" el resultado, debe usar cUrl en modo asíncrono. En este caso, cualquier llamada a la URL no esperará hasta que finalice. Y puedes llamarlos a todos muy rápido.

BR.

1

Si las páginas remotas tardan hasta 5 minutos en cargarse, su file_get_contents se asentará y esperará durante 5 minutos. ¿Hay alguna forma de que pueda modificar los scripts remotos para incorporarlos a un proceso en segundo plano y hacer el procesamiento pesado allí? De esta forma, su golpe inicial regresará casi de inmediato y no tendrá que esperar al período de inicio.

Otra posibilidad es investigar si una solicitud HEAD haría el truco. HEAD no devuelve ningún dato, solo encabezados, por lo que puede ser suficiente para activar los trabajos remotos y no esperar la salida completa.

+0

Me gusta la idea de HEAD, podría valer la pena intentarlo. – svens

2

Como mencioné Franco y no estoy seguro de que haya sido recogido, específicamente desea utilizar las funciones curl_multi, no las de curl normales. Esto agrupa múltiples objetos curl en un objeto curl_multi y los ejecuta simultáneamente, devolviendo (o no, en su caso) las respuestas a medida que llegan.

Ejemplo en http://php.net/curl_multi_init

Cuestiones relacionadas