2009-09-17 9 views

risposta

10

Ecco come farlo. Dite al browser di leggere i primi N caratteri dell'output e quindi chiudete la connessione, mentre il vostro script continua a funzionare finché non viene eseguito.

<?php 
ob_end_clean(); 
header("Connection: close"); 
ignore_user_abort(true); // optional 
ob_start(); 
echo ('Text the user will see'); 
$size = ob_get_length(); 
header("Content-Length: $size"); 
ob_end_flush();  // Will not work 
flush();   // Unless both are called ! 

// At this point, the browser has closed connection to the web server 

// Do processing here 
echo('Text user will never see'); 
?> 
+0

+1 Soluzione brillante! Grazie per la saggezza che tutti i cavalieri del re non riuscivano a capire. –

+0

Davvero un bel trucco di Milano. Ma devo chiedermi che cosa stai facendo che richiede di masticare un processo del server web dopo che la richiesta web è finita (dal punto di vista del cliente). Sicuramente spero che questo abominio non si aspetti in grande scala! – timdev

+3

Identico (alla lettera) al codice nella pagina di manuale php collegata alla risposta di Lukman, che è stata pubblicata due giorni prima. – GZipp

4

intestazioni non funziona (sono intestazioni, in modo da venire prima)

Io non conosco alcun modo per chiudere la connessione HTTP senza terminare la sceneggiatura, anche se suppongo c'è un modo oscuro per farlo.

Dicendoci cosa volete fare dopo che la richiesta è stata fatta ci aiuterebbe a dare suggerimenti migliori.

Ma in generale, mi piacerebbe pensare a una delle seguenti opzioni:

1) eseguire qualche semplice script da riga di comando (usando exec()) che assomiglia:

#!/bin/sh 
php myscript.php <arg1> <arg2> .. <argN> & 

Poi calcio che fuori dal vostro script http-bound come:

<?PHP 
exec('/path/to/my/script.sh'); 
?> 

Oppure:

2) Scrivi anothe r programma (probabilmente un daemon in esecuzione continua, o solo uno script che viene cronnato sempre così spesso), e capire come il codice in-richiesta può passargli le istruzioni. Si può avere una tabella di database in cui funzionano le code o provare a farlo funzionare con un file flat di qualche tipo. Si potrebbe anche fare in modo che lo script basato sul Web richiami un comando da riga di comando che fa in modo che lo script fuori richiesta faccia la coda di lavoro.

Alla fine della giornata, non è vuoi lo script per continuare l'esecuzione dopo la richiesta http. Supponendo che tu stia usando mod_php, significa che dovrai legare un processo apache fino alla fine dello script.

+1

+1 concordato. Continuare l'esecuzione dopo una richiesta Web sarebbe una scelta di progettazione scadente e comporterebbe un sovraccarico di memoria non necessario sul server. – Fragsworth

+0

Grande tempo concordato con Tim. L'intero punto della domanda è che vuoi salvare una parte del lavoro per dopo, e non far aspettare l'utente. Beh, stai solo legando le risorse httpd che potrebbero bloccare altri utenti. Lascia che httpd gestisca i client Web e trasferisca l'altro lavoro a un altro componente: demone (+1 per tempo reale), lavoro pianificato (+1 per l'elaborazione di batch ed elaborazione di accodamento che può VERAMENTE attendere) o qualsiasi altra cosa. –

2

In teoria, se HTTP 1.1 keep-alive è abilitato e il client riceve la quantità di caratteri che si aspetta dal server, dovrebbe trattarlo come la fine della risposta e andare avanti e visualizzare la pagina (mantenendo la connessione . ancora aperto) Provare a inviare queste intestazioni (se non è possibile consentire loro un altro modo):

 
Connection: keep-alive 
Content-Length: n 

Dove n è la quantità di caratteri che hai inviato nel corpo della risposta (il buffering può aiutare a contare quello.) Mi dispiace che non ho il tempo di provarlo da solo. Sto solo lanciando il suggerimento nel caso in cui funzioni.

+0

Ancora una cattiva idea, come se l'elaborazione post-richiesta richiedesse più di qualche ms (nel qual caso perché fretta di terminare la connessione), è meglio rilasciare il processo del server web per gestire nuove richieste, e avere qualche il processo di back-end (non legato a httpd) prende il sopravvento. – timdev

+0

Sono d'accordo che questa è probabilmente una cattiva idea. È solo un tentativo di soddisfare i requisiti dell'OP. –

2

Il modo migliore per raggiungere questo obiettivo sta usando il buffer di uscita. PHP invia le intestazioni quando è buono e pronto, ma se si avvolge l'output nel browser con ob_ * è possibile controllare le intestazioni in ogni fase del processo.

È possibile mantenere una pagina sottoposta a rendering nel buffer se lo si desidera e inviare le intestazioni fino a quando il sole non arriva in Cina. Questa pratica è la ragione per cui si possono vedere molti tag di apertura <?php, ma al giorno d'oggi non ci sono tag di chiusura. Mantiene la sceneggiatura inviando prematuramente le intestazioni poiché potrebbero essere incluse alcune considerazioni.

Problemi correlati