2009-08-14 14 views
37

Quiero ejecutar un script relativamente lento basado en alguna entrada de formulario, pero prefiero no recurrir a cron, así que me pregunto si una página php solicitada a través de ajax continuará ejecutándose hasta que se complete o si se detendrá si el usuario deja la página.¿La ejecución de PHP se detiene después de que un usuario abandona la página?

En realidad, no da salida al navegador hasta un json_encode al final del archivo, por lo que todo lo anterior aún se ejecutará?

Respuesta

67

Depende.

De http://us3.php.net/manual/en/features.connection-handling.php:

Cuando un script PHP está funcionando normalmente el estado normal, se activa. Si el cliente remoto se desconecta, el indicador de estado ABORTED se activará. Una desconexión remota del cliente generalmente es causada por cuando el usuario presiona el botón STOP.

Puede decidir si desea o no una desconexión del cliente para provocar que se interrumpa el script . A veces es útil tener siempre las secuencias de comandos ejecutar hasta su finalización, incluso si no hay navegador remoto que recibe la salida. Sin embargo, el comportamiento predeterminado es al interrumpir el script cuando se desconecta el cliente remoto . Este comportamiento se puede ajustar a través de la ignore_user_abort directiva php.ini como así como a través de la correspondiente directiva httpd.conf php_value ignore_user_abort Apache o con la función ignore_user_abort().

Parece que la respuesta a su pregunta es "Sí, el script terminará si el usuario abandona la página".

Sin embargo, tenga en cuenta que, dependiendo del SAPI de fondo que se utilice (p. Ej., mod_php), php cannot detect that the client has aborted the connection until an attempt is made to send information to the client. Si su script de ejecución larga no emite un flush(), el script puede seguir ejecutándose aunque el usuario haya cerrado la conexión.

Para complicar las cosas es incluso si haces emitir llamadas periódicas a flush(), teniendo en output buffering hará que esas llamadas para atrapar y no enviarlos hacia el cliente hasta que se completa el guión de todos modos!

Además que complica las cosas es si ha instalado controladores de Apache que amortiguan la respuesta (por ejemplo mod_gzip) entonces PHP, una vez más, no se detecta que la conexión se cierra y el guión se mantendrá en el trueque.

Phew.

+5

muy detallado +1 –

6

Depende de su configuración, por lo general se detendrá pero puede usar ignore_user_abort() para que continúe.

+5

Hay una advertencia grande y gordo en http://www.php.net/manual/en/function.ignore-user-abort.php que 'ignore_user_abort()' no se garantiza que funcione si los datos no se puede enviar al cliente, lo que puede suceder en una serie de escenarios. Ver mi respuesta –

1

Dependiendo de la configuración del servidor web y/o PHP, el proceso de PHP puede, o no, matar el hilo cuando el usuario finaliza la conexión HTTP. Si una solicitud AJAX está pendiente cuando el usuario abandona la página, depende de que el navegador anule la solicitud (no se garantiza) ontop de la configuración del servidor (no se garantiza). ¡No es la respuesta que quieres escuchar!

Recomendaría crear una cola de trabajos en un archivo plano o en una base de datos que un PHP daemon que se ejecuta constantemente puede sondear en busca de trabajos. No sufre retraso de cron, pero mantiene el uso de CPU/memoria en un nivel utilizable. Una vez que el trabajo esté completo, coloque los resultados en el archivo plano/base de datos para búsqueda de AJAX. O prometa enviar un correo electrónico al usuario una vez que el trabajo haya finalizado (mi método preferido).

Espero que ayude

0

Si el cliente/usuario/descargador/visor interrumpe o desconecta, la secuencia de comandos seguirá ejecutándose hasta que se intente eliminar los datos nuevos del cliente. A menos que haya usado ignore_user_abort(), la secuencia de comandos morirá allí. En el mismo orden, PHP no puede determinar si el cliente todavía está allí sin intentar vaciar ningún dato al httpd.

Cuestiones relacionadas