8
votes

Comment obtenir une sortie en temps réel de PHP comme ça se produit?

Comment obtenir une sortie en temps réel de PHP comme cela se produit? Sans stocker tout en mémoire / tampon et écho à la fois tout à la fois au navigateur?

Si je crée un réeltime-echo.php p> xxx pré>

et l'accédez à partir du navigateur Internet donne la sortie suivante, après 9-10 secondes. P>

0123456789


0 commentaires

3 Réponses :


8
votes

Utilisez flush () code> fonction lorsque vous souhaitez que la sortie actuelle soit affichée.

Un exemple rapide: p> xxx pré>

Si vous utilisez la mémoire tampon de sortie, vous devez également appeler ob_flush () code> p>

Remarque: certaines versions de Microsoft Internet Explorer ne commencent à afficher que le Page Après avoir reçu 256 octets de sortie, vous devrez peut-être envoyer des espaces supplémentaires avant de rincer pour obtenir ces navigateurs pour afficher la page. P>

quelque chose comme ceci: p>

<?php
echo str_repeat(" ", 256);
for ($i = 1; $i <= 10; $i++)
{
    sleep(1);
    echo '<p>' . $i . '</p>';
    flush();
}
?>


7 commentaires

J'ai essayé votre premier code sur mon wamp et il jette tout à la fois après avoir attendu 10 secondes, j'essaie votre deuxième code


Ok, laissez-moi faire une autre révision.


Toujours la même chose, je suppose que je manque quelque chose, j'ai même ajouté // désactiver la mémoire tampon de sortie ini_set ("sortie_buffering", "OFF"); // désactive la compression de sortie PHP ini_set ('zlib.output_compression', false);


@AmbroseBwangatto, ce code devrait fonctionner. Mais cela a également lié à votre serveur Web. php.net/manual/fr/funfunction.flush.php


Cela fonctionne pour moi: '. $ i. ''; affleurer(); }?>


Notez que le protocole HTTP a un certain emballage à l'esprit, votre sortie ne sera pas présentée en petites étapes car l'emballage prévoit


La sortie de beaucoup d'espaces était en réalité la seule façon de «briser tous les tampons» dans mon cas. J'ai fondamentalement annexé 40k espaces après chaque appel d'écho, et cela le fait. C'est grandement inefficace, mais comme je l'ai dit, dans mon cas, c'était la seule option.



4
votes

php est une langue serveur interprétée. En utilisant PHP, vous pouvez créer des programmes locaux ou implémenter le côté serveur d'une application Web. Si vous exécutez votre code PHP dans la ligne de commande, votre code doit fonctionner comme prévu. Toutefois, si vous utilisez votre PHP via le navigateur, il existe une stratégie de demande de demande applicable à HTTP. Si vous envoyez une demande au navigateur, vous ne recevrez la réponse du serveur lorsque le script a été exécuté . Donc, vous demandez à la page via un navigateur, puis attendez la réponse. Le serveur reçoit la demande et fait écho à dix numéros avec un deuxième sommeil entre eux. Une fois que le serveur a terminé son travail, il renvoie la réponse à votre navigateur qui obtiendra les dix numéros dans un seul lot . C'est pourquoi vous vivez que vous attendez dix secondes, puis toute la sortie est affichée à la fois: c'est parce que le serveur a exécuté les couchages et recueilli vos échos, puis les renvoya à votre navigateur qui l'affichait simplement.

Bien sûr, si vous souhaitez afficher dix réponses de serveur dans votre navigateur, vous devrez faire mieux. Peut-être que vous pouvez utiliser Sondage (en utilisant le setInterval ou le Settimeout Fonction de JavaScript Vous attendez les secondes de votre client et envoyez les demandes postales après cela sur le serveur à l'aide de $. Ajax , Par exemple. Sur le serveur, vous gérez la demande et répondez à la sortie correcte. Votre client doit avoir un rappel où vous gérez la réponse du serveur et l'affiche en conséquence).


4 commentaires

Cela signifie-t-il que Flush () ne fait pas ce que je cherche? Je peux aussi utiliser Ajax si cela résout le problème. Merci


La méthode de sommeil dort avec succès entre vos échos. Cependant, le problème est que PHP envoie la réponse au navigateur exécutant sur l'ordinateur de l'utilisateur après l'exécution du script PHP. Vous devez donc attendre 10 secondes sans voir quoi que ce soit affiché, la réponse arrive et tout est affiché à la fois.


@Lajosarpad, je crois que vous avez commenté le sommeil (), tandis que l'AMB a posé des questions sur Flush () dans son commentaire. Je seconde sa question: la méthode avec Flush () et ob_flush () de Paul travaille pour moi. Mais votre réponse implique que cela ne devrait pas. Précisez s'il vous plaît.


@Texnic j'ai expliqué la raison du comportement de l'AMB décrit. Flush et Ob_Flush tentent d'envoyer le contenu actuel au client.



4
votes

La mémoire tampon de sortie peut être allumée qui empêche la sortie en temps réel. Vous avez donc besoin d'un echo code> en combinaison avec flush () code> et ob_flush () code>.

Source: http://php.net/manual/fr/funcuncuncunk.Ob-flush.php#109314 a > P>

header( 'Content-type: text/html; charset=utf-8' );
echo 'Begin ...<br />';
for( $i = 0 ; $i < 10 ; $i++ ){
    echo $i . '<br />';
    flush();
    ob_flush();
    sleep(1);
}
echo 'End ...<br />';


3 commentaires

J'ai testé votre exemple avec Node.js pour obtenir le flux de PHP et on dirait que cela fonctionne. Cependant, mon service Web a été configuré pour envoyer des morceaux de taille plus grande, de sorte que le streaming pourrait ne pas toujours être immédiatement évident


@Adamf dans le php.ini sur mon serveur, j'ai eu la directive de sortie_buffering, comme ceci: sortie_buffering = 4096 . Comment gérez-vous le problème de la diffusion en continu que vous décrivez?


@Julien, je ne sais pas si cela aide, mais si vous devez modifier les paramètres INI localement sur le code, vous pouvez ajouter une ligne comme celle-ci: ini_set ('sortie_buffering', 512);