2010-11-16 12 views
3

J'ai quelques questions conceptuelles (toutes reliées, je pense) concernant le script suivant, aux commentaires. Le script fonctionne bien.PHP buffer pourquoi?

<?PHP 
ob_start(); 

// Create string to overflow browser buffer ...? 
$buffer = str_repeat(" ", 4096); 

// Indicate new header/html content ...? 
$buffer .= "\r\n<span></span>\r\n"; 

for ($i=0; $i<5; $i++) { 
    echo $buffer.$i; 
    ob_flush(); 
    flush(); 
    sleep(1); 
} 

ob_end_flush(); 
?> 

D'abord, pourquoi dois-je envoyer le \r\n<tag>\r\n au navigateur? Je suppose que cela a quelque chose à voir avec les en-têtes. Deuxièmement, pourquoi ai-je besoin de HTML au milieu? Troisièmement, il y a beaucoup d'exemples qui utilisent 256 octets au lieu de 4096. Cependant, le script ne fonctionne pas si j'utilise 256. Ces exemples sont-ils obsolètes, et ce nombre changera-t-il dans le futur?

// EDIT SOURCE LIENS CONCERNANT

Ce code a été recueillie principalement de la commentary in php.net sleep() function et the solution to this SO question. Aucun des deux ne mentionne pourquoi inclure \r\n.

// EDIT CONCERNANT TÊTES

si je ne fais pas \r\n, une balise HTML, et un second ensemble de \r\n, le script ne sera pas exécuter correctement dans Chrome ou Safari (il dumps simplement toutes les valeurs à une fois que).

En outre, si cela est appelé avant un session_start(), il génère une erreur: "Impossible d'envoyer le limiteur de cache de session - en-têtes déjà envoyés".

+0

Il serait utile de savoir quel est le but du script/résultat attendu. – netcoder

+3

4096 octets est le paramètre de mise en tampon de sortie 'php.ini' par défaut. '\ r \ n' est juste un retour à l'environnement Windows typique. – Phil

+0

D'où avez-vous obtenu ce code? qu'est-ce que c'est censé faire? – cambraca

Répondre

2

First, why do I need to send the \r\n<tag>\r\n to the browser? I assume it has something to do with headers.

Second, why do I need some HTML in the middle?

navigateur normalement attendre jusqu'à ce qu'ils aient tiré par les cheveux la réponse entière jusqu'à ce qu'il soit rendu (il suffit de penser XML qui peut être valide jusqu'à ce que le dernier caractère). Mais comme cela ferait une mauvaise expérience utilisateur, la plupart des navigateurs commencent à analyser et à rendre le contenu le plus tôt possible.

Et ici, ce fragment HTML pourrait être l'initiateur du navigateur pour construire réellement le DOM et commencer le rendu.

Third, there are many examples that use 256 bytes instead of 4096. However, the script doesn't work if I use 256. Are these examples outdated, and will this number change again in the future?

Comme le manuel laisse deviner qu'il pourrait y avoir une mise en mémoire tampon plus intégré dans le serveur web, cela pourrait être la tentative de déborder les tampons qu'ils sont vidées afin d'avoir l'effet escompté.

+0

Cela a aussi du sens. Cependant, le script échoue si j'envoie '\ r \ n sometext \ r \ n'. Cela ne fonctionne qu'avec une étiquette au milieu. Le texte en clair ne déclencherait-il pas le DOM, juste avec un nœud de texte? – Ben

+0

@Steve: Non, évidemment pas. Bien que normalement le champ d'en-tête * Content-Type * spécifie le type de contenu, il existe des situations où cette information est manquante. Il n'y a donc aucun indice sur ce qui est réellement envoyé et à ce moment-là [MIME type sniffing] (http://tools.ietf.org/html/draft-abarth-mime-sniff) a lieu dans la plupart des navigateurs. – Gumbo

1

La raison de l'utilisation de \r\n serait de rendre le résultat de sortie bien vu lors de l'utilisation d'un visionneur de source Windows comme notepad.exe.

Rien à voir avec les en-têtes ici. Voyant que le code utilise les fonctions de bufferisation de sortie, je ne sais pas pourquoi ils ressentent le besoin d'essayer de déborder un buffer de 4kb (le défaut dans un standard php.ini mais plus de professionnels n'opteraient pour aucune bufferisation de sortie par défaut).

+0

Je pense qu'il essaie de déborder le tampon dans le navigateur, puisque en théorie flush() devrait, bien, vider le tampon php, non? – cambraca

+1

@cambraca Un bon nombre de conseils dans la page de manuel 'flush()' - http://php.net/manual/fr/function.flush.php – Phil

+0

la solution à la question SO à laquelle je suis lié dans ma première édition a un Commentaire dans lequel l'auteur déclare "Bien que je doive envoyer des \ n \ n \ n avec le contenu avant que je le vide pour qu'il fonctionne". – Ben

-1
<?php 

if (ob_get_level() == 0) ob_start(); 

for ($i = 0; $i<10; $i++){ 

     echo "<br> Line to show."; 
     echo str_pad('',4096)."\n";  

     ob_flush(); 
     flush(); 
     sleep(2); 
} 

echo "Done."; 

ob_end_flush(); 
?> 
+1

Veuillez ajouter d'autres explications sur ce que vous montrez. – SiKing