-1

PHP 8

I'm using the newest NGINX feature un WHM 96.... I can flip switch on or off to have nginx cache everything and it's working well and very fast.

**** BUT : when I have a script that does lots of echos, NGINX will WAIT untill ALL is processed.

In the SAME exact server, just by turning off NGINX : all echo are being pushed.

Simplest code example

<?php 

for ($x = 0; $x <= 10; $x++) {
        echo "dot "; sleep(1);
    }
?>

with apache => I see dot (wait 1 sec), dot (wait 1 sec), dot (wait 1 sec), dot (wait 1 sec)

with NGINX => I wait 10 sec and see all 10 dot.....

Is there a way to keep NGINX on and have the same echo while processing effect ?

2 Answers 2

0

Basically, apache2 has a smaller buffer, causing it to stream, whereas nginx is buffering your output.

<?php
        
        $multiple = 1;
        $size = 1024 * $multiple;
        for($i = 1; $i <= $size; $i++) {
            echo ".";
        }
        sleep(5);
        echo "Hello World";
    ?>

If you run this example you will see that your browser’s loading indicator didn’t show that data is being received until after five seconds. Now, let’s change $multipe from 1 to 8 and hit refresh. If there are no specific settings configured, you’ll notice the browser telling us it started to receive some data almost immediately, no wait. Not having to wait for five seconds to realize the page has started loading is very good for customer experience.

You might be wondering why we have set $multiple from 1 to 8. The reason behind this is related to the webserver’s buffers. At the first level there is the PHP buffering, which we can check via the output_buffering PHP settings. There may also be something on PHP's back end (CGI, mod_php, FastCGI) buffering and at the end there might be the webserver’s buffering.

Normally, both Nginx and Apache buffer content up to either 4KB or 8KB depending on the operating system being used. Normally, on 64bit operating systems, the limit is 8KB and on 32bit operating systems it is 4KB.

Since nginx and apache2 both share support for PHP, the best way to implement a universal fix is to use the commonly supported layer, PHP.

All in all, what you need is the flush(); and ob_flush(); function to force data out of the buffer. Something like this out to do the trick:

<?php 

for ($x = 0; $x <= 10; $x++) {
        echo "dot "; sleep(1);
        ob_flush();
        flush();
    }
?>

More information here: https://www.php.net/manual/en/function.ob-flush.php

1
  • I tried ob_flush(); flush(); and it's not working, I think it could be related to "buffers"...
    – Jintor
    May 4, 2021 at 18:43
0

According to https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering

I changed the nginx.conf and virtual hosts to have proxy_buffering off; directive as below:

http {
    proxy_buffering off;
}

server {
    proxy_buffering off;
}

and it solved the issue ;)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .