7
votes

PHP: Fermer le flux de sortie

est-il possible de fermer le flux de sortie d'un script PHP? J'ai un script qui doit faire du post-traitement, mais pendant et après le traitement de la poste, il n'enverra plus de données au client, je voudrais donc fermer la connexion avant le traitement de la poste.

Edit: Dans ma candidature, j'ai un cache qui doit être reconstruit de temps en temps. Cependant, je ne veux pas ralentir un utilisateur. Ce que je veux, c'est déterminer à la fin du script si le cache doit être reconstruit. Donc, je veux d'abord fermer le flux de sortie, de sorte que l'utilisateur obtient ses données, puis je souhaite reconstruire le cache. Ce n'est pas vraiment essentiel de le faire, mais je pense qu'il est préférable de fermer la connexion en premier, l'utilisateur ne remarquera donc pas que le cache est en train de reconstruire si cela prend beaucoup de temps.


2 commentaires

Pourquoi avez-vous besoin de faire cela? Pouvez-vous poster un peu de votre code pour nous aider à comprendre un peu plus?


+1 à ce que Jonathan a dit. Dites-nous un peu plus sur la raison pour laquelle vous voulez faire cela.


3 Réponses :



7
votes

Mise à jour forte>

Le moyen de gérer ce cas est une combinaison de mise en mémoire tampon de sortie et des en-têtes HTTP appropriés. P>

de la http / 1.1 Spécification Section 14.10 : P>

http / 1.1 Définit l'option de connexion "Fermer" pour l'expéditeur à signalez que la connexion sera fermée après la fin de la réponse. P> blockQquote>

Donc, si nous passons le long d'un bouton HTTP longueur de contenu em> en plus de Connexion: Fermer em>, le navigateur sait fermer la connexion après la spécifie La longueur de réponse est reçue: p>

  1. tampon tampon toute la sortie de script afin de conserver la capacité d'envoyer des en-têtes li>
  2. Une fois que vous avez les données de sortie complètes, envoyez les en-têtes appropriés sur le client li>
  3. Continuez votre traitement ... mais n'essayez pas d'envoyer une sortie ou que vous recevrez des erreurs car les en-têtes ont été envoyés. LI> ol>

    En outre, soyez prudent car vous pouvez utiliser des limites de temps d'exécution de script dans Web Server SAPI si vous faites trop de traitement. Enfin, vous devez dire à PHP d'ignorer un "utilisateur abandon" dans ce script particulier à l'aide de ignore_user_abort () code> Parce que le navigateur fermera la connexion à la suite de ce que vous faites et que vous voulez PHP pour poursuivre le traitement. P>

    <?php
    
    echo 'before output buffering';
    ob_start();
    echo 'after output buffering';
    $output = ob_get_contents();
    
    // script's only output to this point will be 'before output buffering'
    
    // I changed my mind, send the output ...
    ob_end_flush();
    ?>
    


5 commentaires

La mémoire tampon de sortie maintient toujours le flux de sortie sur le navigateur ouvert. Alors supposons que j'ai besoin de faire du post-traitement qui prend quelques secondes environ, le navigateur attendra que ce post-traitement est effectué. Surtout avec Ajax, cela ralentira beaucoup le webapplication. Je souhaite donc pouvoir fermer la connexion au navigateur. Le navigateur peut donc traiter la sortie, puis continuer avec le post-traitement.


@Tiddo j'ai mis à jour ma réponse avec (ce que je crois, c'est) la solution correcte.


C'est une jolie solution! Je vais essayer cela dans une minute. EDIT: ça marche génial! Merci beaucoup!


@Tiddo une chose de plus - J'ai ajouté que vous devriez appeler ignore_user_abort () en haut de votre script. Cela peut être évident de la liaison manuelle PHP dans ma réponse originale, mais je voulais l'énoncer explicitement. Alors, assurez-vous que vous faites cela :)


D'accord, merci beaucoup! Dans mon script, j'ai également ajouté de la mémoire tampon de sortie pour tout après l'envoi de la sortie d'origine. Donc, si une sortie est envoyée accidentellement, je ne peux que le jeter et le script ne s'écrasera pas.



0
votes

Je n'ai pas assez de réputation pour commenter, mais je veux partager cela dans la réponse @rdlowrey gzip pourrait être un problème.

Si vous avez gzip activé L'en-tête CoDing-coding est toujours défini sur chunked , même si vous essayez de le modifier avec en-tête ("codage de transfert: aucun"); Par conséquent, il n'enverra pas l'en-tête longueur de contenu .

La manière dont je pouvais résoudre ceci utilisait le suivant avant: xxx

puis la solution: xxx


0 commentaires