Domanda

Sto cercando di creare uno script PHP, ho finito lo script ma ci vogliono circa 10 minuti per completare il processo che è stato progettato. Questo non è un problema, tuttavia presumo che debba mantenere la pagina caricata per tutto questo tempo, il che è fastidioso. Posso averlo in modo da avviare il processo e poi tornare dopo 10 minuti e visualizzare semplicemente il file di registro che ha generato?

È stato utile?

Soluzione

Bene, puoi usare " ignore_user_abort (vero) <> quot;

Quindi lo script continuerà a funzionare (tieni d'occhio la durata dello script, forse aggiungi " set_time_limit (0) ")

Ma qui un avvertimento: non sarai in grado di interrompere uno script con queste due righe:

ignore_user_abort(true); 
set_time_limit(0);

Tranne che puoi accedere direttamente al server e terminare il processo lì! (Sono stato lì, ho fatto un ciclo infinito, chiamandosi più e più volte, fatto arrestare il server, gridando ...)

Altri suggerimenti

Sembra che dovresti avere una coda e uno script esterno per l'elaborazione della coda.

Ad esempio, lo script PHP dovrebbe inserire una voce in una tabella del database e tornare immediatamente. Quindi, un cron in esecuzione ogni minuto controlla la coda e avvia un processo per ciascun processo.

Il vantaggio qui è che non si blocca un thread di Apache per 10 minuti.

Ho avuto molti problemi con questo tipo di processo in Windows; La mia situazione era un po 'diversa in quanto non mi interessava la risposta del & Quot; script & Quot; - Volevo che lo script si avviasse e consentissi che altre richieste di pagina passassero mentre era occupato a lavorare via .

Per qualche motivo; Ho avuto problemi con l'attesa di altre richieste o il timeout dopo circa 60 secondi (sia apache che php sono stati impostati per il timeout dopo circa 20 minuti); Si scopre anche che firefox scade dopo 5 minuti (per impostazione predefinita), quindi dopo quel punto non puoi sapere cosa sta succedendo attraverso il browser senza modificare le impostazioni in Firefox.

Ho finito per usare i metodi di apertura e di chiusura del processo per aprire un php in modalità cli in questo modo:

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

Questo (usando start) aprirà il processo php e quindi interromperà il processo di avvio lasciando php in esecuzione per il tempo necessario - di nuovo dovresti interrompere il processo per arrestarlo manualmente. Non è necessario impostare alcun timeout e potresti lasciare che la pagina corrente che lo chiamava continui e produrre altri dettagli.

L'unico problema con questo è che se è necessario inviare allo script qualsiasi dato, lo si dovrebbe fare tramite un'altra fonte o passarlo lungo la " riga di comando " come parametri; che non è così sicuro.

Ha funzionato bene per ciò di cui avevamo bisogno e garantisce che lo script si avvii sempre e sia autorizzato a funzionare senza interruzioni.

Questo può essere di aiuto, anche: Exec shell asincrono in PHP

Penso che il comando shell_exec sia quello che stai cercando.

Tuttavia, è disabilitato in modalità provvisoria.

L'articolo del manuale di PHP al riguardo è qui: http://php.net/shell_exec

C'è un articolo a riguardo qui: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/

C'è un'altra opzione che puoi usare, eseguire lo script CLI ... Funzionerà in background e puoi anche eseguirlo come cronjob se vuoi.

ad esempio

> #!/usr/bin/php -q

<?php

//process logs

?>

Questo può essere impostato come cronjob e verrà eseguito senza limiti di tempo .... questo esempio è per il sistema operativo basato su unix.

FYI Ho uno script php in esecuzione con un ciclo infinito che fa un po 'di elaborazione ed è stato in esecuzione negli ultimi 3 mesi ininterrottamente.

Puoi usare ignore_user_abort() - in questo modo lo script continuerà a funzionare anche se chiudi il tuo browser o vai a un'altra pagina.

Pensa a Gearman

  

Gearman è un framework applicativo generico per il lavoro agricolo   più macchine o processi. Consente il completamento delle applicazioni   attività in parallelo, per elaborare l'elaborazione del bilanciamento e per chiamare funzioni   tra le lingue. Il framework può essere utilizzato in una varietà di   applicazioni, dai siti Web ad alta disponibilità al trasporto di   eventi di replica del database.

     

Questa estensione fornisce classi per la scrittura di client Gearman e   lavoratori.   - Manuale php di origine

Sito web ufficiale di Gearman

Oltre alla risposta di bastiandoeen puoi combinare ignore_user_abort(true); con una richiesta cUrl .

Falsa richiesta di aborto impostando un valore basso CURLOPT_TIMEOUT_MS e continua l'elaborazione dopo la chiusura della connessione:

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

  

Se vuoi che cURL scada in meno di un secondo, puoi usare   CURLOPT_TIMEOUT_MS, sebbene sia presente un bug / & Quot; feature & Quot; su " Unix-like   & Sistemi quot; ciò causa immediatamente il timeout di libcurl se il valore è <   1000 ms con errore & Quot; errore cURL (28): Timeout raggiunto & Quot ;. Il   la spiegazione per questo comportamento è:

     

[...]

     

La soluzione è disabilitare i segnali usando CURLOPT_NOSIGNAL

Pro

  • Non è necessario cambiare metodo (Windows compatibile & amp; linux)
  • Non è necessario implementare la gestione della connessione tramite intestazioni e buffer (indipendente dalla versione del browser e PHP)

contro

  • È necessaria l'estensione del ricciolo

Risorse

Zuk.

Sono abbastanza sicuro che funzionerà:

<?php 

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

?>

L'amplificatore '&;' è importante. Indica alla shell di non attendere la chiusura del processo.

Inoltre puoi usare questo codice nel tuo php (come " bastiandoeen " detto)

ignore_user_abort(true); 
set_time_limit(0);

nel comando di arresto del server:

<?php

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

?>

Basta chiamare StartBuffer () prima di qualsiasi output e EndBuffer () quando si desidera che il client chiuda la connessione. Il codice dopo aver chiamato EndBuffer () verrà eseguito sul server senza connessione client.

    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);
    }

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top