Est-il possible d'écho à chaque exécution de la boucle? Par exemple:
foreach(range(1,9) as $n){
echo $n."\n";
sleep(1);
}
Au lieu de tout imprimer à la fin de la boucle, j'aimerais qu'elle affiche chaque résultat à la fois.
SOLUTION FINALE
C'est ce que j'ai découvert:
Flush ne fonctionnerait pas avec le mod_gzip d’Apache ni avec le gzip de Nginx car, logiquement, il gzippait le contenu. Pour ce faire, il devait mettre le contenu en tampon pour le gzip. Tout type de serveur Web gzipping aurait une incidence sur cela. En bref, côté serveur, nous devons désactiver gzip et réduire la taille de la mémoire tampon de fastcgi. Alors:
Dans php.ini:
. output_buffering = Off
. zlib.output_compression = Off
Dans nginx.conf:
. gzip off;
. proxy_buffering off;
Ayez également ces lignes sous la main, spécialement si vous n'avez pas accès à php.ini:
@ini_set ('zlib.output_compression', 0);
@ini_set ('implicit_flush', 1);
@ob_end_clean ();
set_time_limit (0);
Enfin, si vous en avez un, commentez le code ci-dessous:
ob_start ('ob_gzhandler');
ob_flush ();
PHP code de test:
ob_implicit_flush(1);
for($i=0; $i<10; $i++){
echo $i;
//this is for the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
sleep(1);
}
En relation:
Le moyen le plus simple d’éliminer la mise en mémoire tampon de nginx consiste à émettre un en-tête:
header('X-Accel-Buffering: no');
Ceci élimine à la fois proxy_buffering
et (si vous avez nginx> = 1.5.6), fastcgi_buffering
. Le bit fastcgi est crucial si vous utilisez php-fpm. L'en-tête est également beaucoup plus pratique à faire selon les besoins.
Solution facile sur le serveur nginx:
fastcgi_keep_conn on; # < solution
proxy_buffering off;
gzip off;
Je ne voulais pas avoir à désactiver gzip pour tout le serveur ou tout un répertoire, juste pour quelques scripts, dans quelques cas spécifiques.
Tout ce dont vous avez besoin est ceci avant que quoi que ce soit ne soit répercuté:
header('Content-Encoding: none;');
Ensuite, faites la chasse comme d'habitude:
ob_end_flush();
flush();
Nginx semble comprendre que l'encodage a été désactivé et ne gzip pas.
Vous devez vider le tampon php dans le navigateur
foreach(range(1,9) as $n){
echo $n."\n";
flush();
sleep(1);
}
J'ai trouvé que vous pouvez définir:
header("Content-Encoding:identity");
dans votre script php pour désactiver nginx gzipping sans avoir à modifier le nginx.conf
Vous pouvez accomplir cela en vidant le tampon de sortie au milieu de la boucle.
Exemple:
ob_start();
foreach(range(1,9) as $n){
echo $n."\n";
ob_flush();
flush();
sleep(1);
}
Notez que vos paramètres php.ini peuvent déterminer si cela fonctionnera ou non si la compression zlib est activée.
J'ai eu un problème avec gzip venant de mon moteur php-fpm. Ce code est le seul qui fonctionne pour moi:
function myEchoFlush_init() {
ini_set('zlib.output_compression', 0);
ini_set('output_buffering', 'Off');
ini_set('output_handler', '');
ini_set('implicit_flush', 1);
ob_implicit_flush(1);
ob_end_clean();
header('Content-Encoding: none;');
}
function myEchoFlush($str) {
echo $str . str_repeat(' ', ini_get('output_buffering') * 4) . "<br>\n";
}
Ceci est ma fonction de test: elle vérifie max_execution_time:
public function timeOut($time = 1, $max = 0) {
myEchoFlush_init();
if ($max) ini_set('max_execution_time', $max);
myEchoFlush("Starting infinite loop for $time seconds. It shouldn't exceed : " . (ini_get('max_execution_time')));
$start = microtime(true);
$lastTick = 1;
while (true) {
$tick = ceil(microtime(true) - $start);
if ($tick > $lastTick) {
myEchoFlush(microtime(true) - $start);
$lastTick = $tick;
}
if ($tick > $time) break;
}
echo "OK";
}