Notez que vous devez redémarrer la ligne de service Apache après avoir modifié php.ini !
for($i=0;$i<10;$i++) { echo $i.'<br />'; flush(); sleep(1); }
Les amis qui ont découvert la fonction de contrôle de sortie du cache PHP doivent être familiers avec le code ci-dessus. L'effet qu'il souhaite obtenir est de générer 1 nombre toutes les 1 seconde, ce qui est nécessaire pour. terminez toutes les sorties en 10 secondes, mais vous découvrirez des phénomènes étranges dans l'exécution réelle. Certaines personnes ou parfois, cela fonctionne comme vous l'attendez, tandis que certaines personnes ou parfois, il génère 10 nombres à la fois après 10 secondes. J'en devenais fou. Un ami a laissé un message disant que cette situation est souvent due au fait que le cache d'IE doit atteindre 256 caractères avant la sortie. Mais en fait, j'ai également examiné la situation d'IE auparavant, mais cela fonctionne encore parfois et parfois non. Ça ne marche pas. Après avoir lu attentivement le manuel aujourd'hui, j'ai réalisé qu'il y avait des raisons à ces phénomènes imprévisibles.
Il s'avère qu'il y a deux paramètres clés dans php.ini qui affecteront le contrôle de sortie du cache de php :
Paramètre 1 : output_buffering : on/off ou entier. Lorsqu'il est activé, le contrôle du cache de sortie sera utilisé dans tous les scripts sans limiter la taille du cache. Lorsqu'il est défini sur un nombre entier, tel que output_buffering=4096, lorsque les données du cache atteignent 4096 octets, le cache sera automatiquement actualisé. La différence entre ce paramètre est la raison pour laquelle le code ci-dessus a des résultats d'exécution différents à des moments différents. Lorsque output_buffering est désactivé, toutes les sorties (écho) du script seront immédiatement envoyées au client. Lorsque le code ci-dessus est exécuté, un nombre sera généré chaque seconde. Une fois output_buffering activé, le contenu de sortie sera d'abord mis en cache sur le serveur et ne sera envoyé au client qu'à la fin du script.
Paramètre 2 : implicit_flush : on/off. La définition sur ON signifie que lorsque le script est sorti, il est automatiquement envoyé immédiatement au client. Cela équivaut à ajouter automatiquement flush() après echo.
Fonctions associées au contrôle de sortie du cache PHP :
ob_start()
Premier paramètre : Fonction de rappel , facultatif. La sortie peut être filtrée ou autrement traitée avant d'être mise en cache. L'utilisation la plus courante est ob_start('ob_gzhandler'), qui compresse par gzip les données mises en cache avant de les envoyer au client.
Le deuxième paramètre : la taille du bloc de cache, facultatif. Si le contenu mis en cache atteint ou manipule la taille du bloc de cache, le cache sera automatiquement éjecté. La valeur par défaut est 0, ce qui signifie que la taille n'est pas limitée et que le cache est mis en cache jusqu'à la fin. Il existe également une valeur spéciale 1, qui représente chunk_size=4096.
Le troisième paramètre : s'il faut vider le cache, facultatif, la valeur par défaut est true, s'il est défini sur false, le cache ne sera pas vidé avant la fin de l'exécution du script.
Vous pouvez utiliser ob_get_contents() pour obtenir les données mises en cache par le serveur sous la forme d'une chaîne, et utiliser ob_end_flush() pour obtenir les données de sortie mises en cache et désactiver la mise en cache.
L'utilisation de ob_end_clean() effacera silencieusement les données mises en cache sur le serveur sans aucune donnée ni autre action.
Les caches côté serveur sont empilés, ce qui signifie qu'après avoir activé ob_start() et avant de le fermer, vous pouvez ouvrir un autre cache ob_start() à l'intérieur. Cependant, vous devez également vous assurer qu'il existe autant d'opérations pour désactiver le cache que d'opérations pour activer le cache.
ob_start() peut spécifier une fonction de rappel pour traiter les données mises en cache. Si un ob_start() est imbriqué dans un autre
ob_start(), nous supposons que l'extérieur. le nombre d'ob_start() de la couche est A, et le nombre d'ob_start() de la couche interne est B. Ils ont chacun une fonction de rappel appelée functionA et functionB. Ensuite, lorsque les données du cache B sont sorties, elles seront traitées. par la fonction de rappel funcitonB, puis transmis à la fonction de rappel externe functionA pour le traitement, puis peut être envoyé au client.
De plus, le manuel indique que pour certains serveurs Web, comme Apache, l'utilisation de la fonction de rappel peut modifier le répertoire de travail actuel du programme. La solution consiste à modifier manuellement le programme. dans la fonction de rappel. Pour modifier le répertoire de travail, utilisez la fonction chdir Cela ne semble pas être rencontré souvent. N'oubliez pas de consulter le manuel lorsque vous le rencontrez.
flush() et ob_flush()
L'utilisation de ces deux fonctions est probablement le problème le plus déroutant pour de nombreuses personnes. L'explication des deux fonctions dans le manuel. n'est pas non plus clair. Le langage n'est pas clair et la différence entre eux n'est pas clairement soulignée. Il semble que la fonction des deux soit d'actualiser le cache de sortie. Mais dans le code au début de notre article, si flush() est remplacé par ob_flush(), le programme ne s'exécutera plus correctement. Évidemment, il y a une différence entre eux. Sinon, il suffirait d'indiquer directement dans le manuel que l'un d'eux est un alias d'une autre fonction. Il n'est pas nécessaire de les expliquer séparément. Alors, quelle est la différence entre eux ?
反复研究了手册的说明,参考了手册中一些人的留言,自己琢磨应该是这样的:
在没有开启缓存时,脚本输出的内容都在服务器端处于等待输出的状态,flush()可以将等待输出的内容立即发送到客户端。
开启缓存后,脚本输出的内容存入了输出缓存中,这时没有处于等待输出状态的内容,你直接使用flush()不会向客户端发出任何内容。而ob_flush()的作用就是将本来存在输出缓存中的内容取出来,设置为等待输出状态,但不会直接发送到客户端,这时你就需要先使用ob_flush()再使用flush(),客户端才能立即获得脚本的输出。
也就是说本文开头的脚本,可以根据缓存开启与否,有如下几种不同的写法:
注:以下代码都未考虑IE缓存必须大于256字节才输出的问题,如在IE下测试,请在代码开始加一句:“echo str_repeat('',256)”
写法1:
output_buffering = off implicit_flush=off for($i=0;$i<10;$i++) { echo $i.'<br />'; flush(); sleep(1); }
写法2:
output_buffering = on implicit_flush=off for($i=0;$i<10;$i++) { echo $i.'<br />'; ob_flush(); flush(); sleep(1); }
写法3:
output_buffering = off implicit_flush=off ob_start(); for($i=0;$i<10;$i++) { echo $i.'<br />'; ob_flush(); flush(); sleep(1); }
写法4:
output_buffering = on implicit_flush=off ob_end_flush(); for($i=0;$i<10;$i++) { echo $i.'<br />'; flush(); sleep(1); }
写法5:
output_buffering = on implicit_flush=off ob_end_clean(); for($i=0;$i<10;$i++) { echo $i.'<br />'; flush(); sleep(1); }
写法6:
output_buffering = on; implicit_flush=on ob_end_clean(); // 或者ob_end_flush(); for($i=0;$i<10;$i++) { echo $i.'<br />'; sleep(1); }
写法7:
output_buffering = on; implicit_flush=on ob_end_clean(); // 或者ob_end_flush(); for($i=0;$i<10;$i++) { echo $i.'<br />'; flush(); sleep(1); }
写法8:
output_buffering = off implicit_flush=on for($i=0;$i<10;$i++) { echo $i.'<br />'; sleep(1); }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!