PHP: Come restituire le informazioni a uno script in attesa e continuare l'elaborazione


6

Supponiamo che ci siano due script Requester.php e Provider.php, e Richiedente richiede l'elaborazione da parte del Provider e fa una richiesta http (Provider.php? Data = " dati"). In questa situazione, Provider trova rapidamente la risposta, ma per mantenere il sistema è necessario eseguire vari aggiornamenti in tutto il database. Esiste un modo per restituire immediatamente il valore a Requester e quindi continuare l'elaborazione in Provider.

Psuedo Codice

Provider.php 
{ 
    $answer = getAnswer($_GET['data']); 
    echo $answer; 
    //SIGNAL TO REQUESTER THAT WE ARE FINISHED 
    processDBUpdates(); 
    return; 
} 
1

In genere si desidera segnalare la fine di 1 processo (ritorno allo Requester.php originale) e generare un nuovo processo (finitura Provider.php). C'è probabilmente un modo più elegante per farlo, ma ho gestito questo un paio di modi diversi. Tutti fondamentalmente si traducono nell'esecuzione di un comando al fine di eliminare il secondo processo.

aggiungendo la seguente > /dev/null 2>&1 & alla fine del vostro comando permetterà l'esecuzione in background senza inibire l'effettiva esecuzione dello script corrente

qualcosa del genere può funzionare per voi:

exec("wget -O - \"$url\" > /dev/null 2>&1 &"); 

- sebbene tu possa farlo come un comando PHP da riga di comando.

È inoltre possibile salvare le informazioni che devono essere elaborate e gestire l'elaborazione rimanente in un processo cron che ricrea lo stesso tipo di funzionalità senza la necessità di eseguire.


2

È possibile svuotare il buffer di uscita con il comando a filo().
leggere i commenti nel PHP manual per ulteriori informazioni


0

Spalato il provider in due: ProviderCore e ProviderInterface. In ProviderInterface basta fare la parte "facile e veloce", anche salvare un flag nel database che la richiesta recente non è stata ancora elaborata. Esegui ProviderCore come un cron job che cerca quel flag e completa l'elaborazione. Se non c'è niente da fare, ProviderCore terminerà e riproverà (diciamo) 2 minuti.


1

Penso che avrete bisogno sul provider di inviare i dati (assicuratevi di svuotare), e poi sul Richiedente, usate fopen/fread per leggere una quantità prevista di dati, in modo da poter lasciare la connessione al Provider e continua. Se non si specifica una quantità di dati da prevedere, penserei che il richiedente si sieda in attesa che il provider chiuda la connessione, il che probabilmente non avviene fino alla fine della sua esecuzione (ad esempio, tutto il lavoro secondario intensivo le attività sono complete). Avrai bisogno di provare alcuni POC ..

Buona fortuna.


2

Io uso this code per eseguire un processo in background (funziona su Linux).

Il processo viene eseguito con il relativo output reindirizzato a un file.

In questo modo, se è necessario visualizzare lo stato del processo, è solo questione di scrivere una piccola quantità di codice per leggere e visualizzare il contenuto del file di output.

Mi piace questo approccio perché significa che è possibile chiudere completamente il browser e tornare facilmente in seguito per verificare lo stato.


0

Qui sto andando su un arto, ma forse dovresti provare cURL o usare un socket per aggiornare il richiedente?


0

Si potrebbe avviare un altro processo in php Provider.php utilizzando pcntl_fork()

Provider.php 
{ 
    // Fork process 
    $pid = pcntl_fork(); 

    // You are now running both a daemon process and the parent process 
    // through the rest of the code below 

    if ($pid > 0) { 
     // PARENT Process 
     $answer = getAnswer($_GET['data']); 
     echo $answer;  
     //SIGNAL TO REQUESTER THAT WE ARE FINISHED 
     return; 
    } 

    if ($pid == 0) { 
     // DAEMON Process 
     processDBUpdates(); 
     return; 
    } 

    // If you get here the daemon process failed to start 
    handleDaemonErrorCondition(); 
    return; 

}