2010-01-21 12 views
5

Estoy tratando de rastrear lo que parece ser un error muy extraño. Tengo una aplicación que está estructurada aproximadamente de la siguiente manera:¿Puede finalizar el script PHP aunque se haya establecido set_time_limit (0)?

set_time_limit(0); 
register_shutdown_function('logScriptCompletion'); 

function logScriptCompletion() { 
    log('script completed'); 
} 

log('script started'); 

// do some calculations periodically printing out progress 

El script puede tomar un tiempo para ejecutarse. El comportamiento deseado es que la secuencia de comandos continúe computando hasta el final, incluso si se pulsa el botón de detención o se interrumpe la conexión. El 99% del tiempo funciona como se esperaba.

De vez en cuando (tal vez una vez cada pocos meses/un par de miles de solicitudes) el cálculo no se ejecuta completamente, pero tanto "secuencia de comandos iniciada" como "secuencia de comandos completada" se registran y ningún otro error es fatal o no aparente (tengo el registro completo habilitado).

Tengo la sospecha de que esto puede tener algo que ver con la conexión al servidor que se descarta, pero no tengo pruebas que confirmar. Estoy ejecutando Apache 2/PHP 5.2.6 en Linux.

¿Alguien más ha visto un problema similar y puede ayudar a arrojar algo de luz sobre esto?

Respuesta

9

¡Absolutamente! También debe usar para usar el ignore_user_abort() function.

+0

Interesante. No tenía este conjunto, pero el script continuaría ejecutándose después de presionar el botón de detener independientemente. Eso podría deberse a la forma en que se realiza el almacenamiento en búfer ... Gracias por la sugerencia, voy a probar esto. –

4

Como una idea, a veces pienso que es una mejor idea ejecutar tales scripts usando la versión de línea de comando de php desde un trabajo cron regularmente programado. (De lo contrario, el procesamiento finalizará si httpd se reinicia por algún motivo, etc.)

Como tal, utilizaría el sitio web para registrar el hecho de que necesita ejecutar un trabajo de procesamiento en segundo plano (en una tabla de base de datos ejemplo) y carga cualquier información para ser procesada. El script cron ejecutado PHP verificará si hay trabajos pendientes en la base de datos, marcando el trabajo como en progreso una vez que comenzó la ejecución, y luego actualiza un campo 'porcentaje completado' en la tabla de la base de datos, que el sitio web podría leer. informar al usuario del progreso.

cuando se procesan era completa, PHP sería actualizar la base de datos en consecuencia, que marca el trabajo como procesado y envío por correo electrónico al usuario si así se desea, etc.

NB: Se puede extender de forma útil este enfoque mediante la adición de algunos campos de fecha y hora básicas para el inicio y el final del procesamiento, por lo tanto, proporciona un medio de comprobación trivial para ver si hay trabajos que se han estado ejecutando durante un largo período de tiempo, etc.

+0

+1, creo que esta es una excelente respuesta informativa. –

+0

Buen punto sobre el registro. En cuanto a ejecutar a través de CLI, esto es algo que definitivamente haré en algún momento, pero lamentablemente esto requiere una refactorización de código significativa en nuestra aplicación. Con respecto al reinicio de http ... Me pregunto si al hacer "httpd graceful" aún se terminan las secuencias de comandos PHP en ejecución. –

Cuestiones relacionadas