Pregunta

Estoy tratando de hacer un script de PHP, tengo el guión terminado, pero se tarda como 10 minutos para finalizar el proceso está diseñado para hacer.Esto no es un problema, sin embargo supongo que tengo que mantener la carga de página de todo este tiempo en que es molesto.Puede que la tengo para que me inicie el proceso y, a continuación, volver 10 minutos más tarde y acabo de ver el archivo de registro que se ha generado?

¿Fue útil?

Solución

Bueno, puede usar " ignore_user_abort (verdadero) "

Entonces el script continuará funcionando (vigile la duración del script, quizás agregue " set_time_limit (0) ")

Pero una advertencia aquí: no podrá detener un script con estas dos líneas:

ignore_user_abort(true); 
set_time_limit(0);

¡Excepto que puede acceder directamente al servidor y eliminar el proceso allí! (Estuve allí, hice un bucle sin fin, llamándose una y otra vez, hizo que el servidor se detuviera, me gritaron a ...)

Otros consejos

Parece que debería tener una cola y un script externo para procesar la cola.

Por ejemplo, su script PHP debería poner una entrada en una tabla de base de datos y regresar de inmediato. Luego, un cron que se ejecuta cada minuto verifica la cola y bifurca un proceso para cada trabajo.

La ventaja aquí es que no bloquea un hilo de Apache durante 10 minutos.

Tuve muchos problemas con este tipo de proceso en Windows; Mi situación era un poco diferente, ya que no me importaba la respuesta del & Quot; script & Quot; quería que el script comenzara y permitiera que otras solicitudes de página se procesaran mientras estaba ocupado trabajando lejos .

Por alguna razón; Tuve problemas con el bloqueo de otras solicitudes o el tiempo de espera después de aproximadamente 60 segundos (tanto apache como php se configuraron para que se agotara después de aproximadamente 20 minutos); También resulta que Firefox agota el tiempo de espera después de 5 minutos (por defecto) de todos modos, así que después de ese punto no puede saber qué está pasando a través del navegador sin cambiar la configuración en Firefox.

Terminé usando el proceso de abrir y cerrar métodos de proceso para abrir un php en modo cli de esta manera:

pclose(popen("start php myscript.php", "r"));

Esto (usando inicio) abriría el proceso de php y luego cerraría el proceso de inicio dejando php en ejecución por el tiempo que fuera necesario; nuevamente, necesitaría eliminar el proceso para apagarlo manualmente. No era necesario que configurara ningún tiempo de espera y podía dejar que la página actual que lo llamaba continuara y generar más detalles.

El único problema con esto es que si necesita enviar al script cualquier dato, lo haría a través de otra fuente o lo pasaría a lo largo de " línea de comando " como parámetros; que no es tan seguro.

Sin embargo, funcionó muy bien para lo que necesitábamos y garantiza que el script siempre se inicie y se permita que se ejecute sin interrupciones.

Esto puede ser de ayuda, también: Asynchronous shell exec en PHP

Creo que el comando shell_exec es lo que está buscando.

Sin embargo, se desactiva en modo seguro.

El artículo del manual de PHP al respecto está aquí: http://php.net/shell_exec

Hay un artículo al respecto aquí: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/

Hay otra opción que puede usar, ejecutar el script CLI ... Se ejecutará en segundo plano e incluso puede ejecutarlo como un cronjob si lo desea.

por ejemplo

> #!/usr/bin/php -q

<?php

//process logs

?>

Esto se puede configurar como un cronjob y se ejecutará sin límite de tiempo ... sin embargo, este ejemplo es para un sistema operativo basado en Unix.

FYI Tengo un script php ejecutándose con un bucle infinito que procesa un poco y se ha estado ejecutando durante los últimos 3 meses sin parar.

Puede usar ignore_user_abort() - de esa manera el script continuará ejecutándose incluso si cierra su navegador o vaya a una página diferente.

Piensa en Gearman

  

Gearman es un marco de aplicación genérico para cultivar el trabajo para   Múltiples máquinas o procesos. Permite completar aplicaciones   tareas en paralelo, para procesar el equilibrio de carga y para llamar a funciones   entre idiomas El marco se puede utilizar en una variedad de   aplicaciones, desde sitios web de alta disponibilidad hasta el transporte de   eventos de replicación de bases de datos.

     

Esta extensión proporciona clases para escribir clientes Gearman y   trabajadores   - Fuente manual de php

Sitio web oficial de Gearman

Además bastiandoeen la respuesta puede combinar ignore_user_abort(true); con un solicitud cUrl.

Falso una solicitud de aborto el establecimiento de un bajo CURLOPT_TIMEOUT_MS y mantener el procesamiento después de la conexión cerrada:

function async_curl($background_process=''){

    //-------------get curl contents----------------

    $ch = curl_init($background_process);
    curl_setopt_array($ch, array(
        CURLOPT_HEADER => 0,
        CURLOPT_RETURNTRANSFER =>true,
        CURLOPT_NOSIGNAL => 1, //to timeout immediately if the value is < 1000 ms
        CURLOPT_TIMEOUT_MS => 50, //The maximum number of mseconds to allow cURL functions to execute
        CURLOPT_VERBOSE => 1,
        CURLOPT_HEADER => 1
    ));
    $out = curl_exec($ch);

    //-------------parse curl contents----------------

    //$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
    //$header = substr($out, 0, $header_size);
    //$body = substr($out, $header_size);

    curl_close($ch);

    return true;
}

async_curl('http://example.com/background_process_1.php');

NB

Si desea cURL para que el tiempo de espera en menos de un segundo, puede utilizar CURLOPT_TIMEOUT_MS, aunque no es un bug/"característica" en "Unix-like los sistemas de" que hace que libcurl para tiempo de espera inmediatamente si el valor es < 1000 ms con el error "cURL de Error (28):El tiempo de espera fue alcanzado".El la explicación para este comportamiento es:

[...]

La solución es deshabilitar el uso de señales CURLOPT_NOSIGNAL

pros

  • No hay necesidad de cambiar los métodos (Compatible con windows y linux)
  • No hay necesidad de implementar la conexión de la manipulación a través de los encabezados y buffer (Independiente del Navegador y la versión de PHP)

contras

  • Necesidad extensión curl

Recursos

Zuk.

Estoy bastante seguro de que esto funcionará:

<?php 

pclose(popen('php /path/to/file/server.php &'));
echo "Server started. [OK]"; 

?>

El amplificador '&;' es importante. Le dice al shell que no espere a que salga el proceso.

También puede usar este código en su php (como " bastiandoeen " said)

ignore_user_abort(true); 
set_time_limit(0);

en el comando de detención del servidor:

<?php

$output;
exec('ps aux | grep -ie /path/to/file/server.php | awk \'{print $2}\' | xargs kill -9 ', $output);
    echo "Server stopped. [OK]";

?>

Simplemente llame a StartBuffer () antes de cualquier salida, y EndBuffer () cuando desee que el cliente cierre la conexión. El código después de llamar a EndBuffer () se ejecutará en el servidor sin conexión del cliente.

    private function StartBuffer(){
        @ini_set('zlib.output_compression',0);
        @ini_set('implicit_flush',1);
        @ob_end_clean();
        @set_time_limit(0);
        @ob_implicit_flush(1);
        @ob_start();
    }

    private function EndBuffer(){
        $size = ob_get_length();
        header("Content-Length: $size");
        header('Connection: close');
        ob_flush();ob_implicit_flush(1);
    }

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top