I have an object for tasks and on __deconstruct(), it's meant to run some of the lengthier cleanup tasks after the rest of the page has already loaded. Unfortunately, it buffers the output and won't send it until after the tasks are finished (nothing is printed in the tasks).
I've read through http://www.php.net/flush and tried all the suggestions there. Obviously I've tried disabling output_buffering in php.ini. I've disabled deflate_module, zlib compression is off, don't have mod_gzip. Calling flush() or ob_flush() has no effect, nor does enabling implicit_flush.
I'm just running XAMPP (currently apache 2.2.17, php 5.3.4) under Windows Server 2008 R2. PHP is being run as a module.
And yes, I could set up some little AJAX hack to run the task manager or even set up a scheduled task to run this specific task, but output buffering has been an issue elsewhere, too. Would just like it to be gone sometimes.
From a similar thread, someone suggested seeing what the following would do:
<?php
while (TRUE)
{
echo 'x';
flush();
sleep(1);
}
?>
As expected, the page displays nothing until the maximum execution time is reached, at which point it flushes the buffer.
This has become extremely frustrating. Anyone have any ideas what could still be causing it to buffer?
You're only sending a small amount of data. Browsers have their own buffer, which can be based on a number of bytes, by which elements have been received, or by something else.
In short, there is nothing you can do about this. The buffering is happening client-side, not server-side. You could try sending more data before your xs.
You can prove this by packet sniffing the connection between the server and the browser, with Wireshark or similar.
hmmm, interesting grabbed a snip of code I have used else where and it works as expected...
https://stackoverflow.com/a/9728519/632951
<?php
echo str_repeat('fillerbytes',20*1024/strlen('fillerbytes'));
echo '<body style="font-size:6px;font-family:arial;">';
echo str_repeat('<br>',2);
for($i=1; $i<=5000; $i++){
echo $i . ' ';
ob_flush();
flush();
usleep(2000); // 2 ms each = 10s total
}
?>
Watch my server count to 5000 http://atwebresults.com/texttest/new.php
(Doesn't work on some free hosts like freehostingeu.com.)
Related
I'm working in PHP and creating a system with a lot of PHP-driven elements and I have noticed that some of my pages stop displaying text produced using the echo command.
I have made a small example of this. Of course, my program is not supposed to just print allt numbers from 1 to 10000, but this example demonstrates how the script just terminates without any warnings.
Example code:
<?php
for ($i = 1; $i <= 10000; $i++) {
echo $i, '<br>';
}
?>
Output:
1
2
More numbers...
8975
8976
8977
8
What is causing this? Is it a buffer issue, and how do I resolve it?
The fact that your code ran to completion on the cli suggests to me that your script is exceeding the ini.max_execution_time runtime configuration.
Note in the linked documentation that the value of this configuration on the cli is 0 which means it does not time out when run in that environment.
The default setting in the browser is 30 seconds.
You can show your current setting in the browser with:
echo ini_get('max_execution_time');
And you should be able to increase it with:
ini_set('max_execution_time', 0); // turns off timeout
If the script you have shown us behaves as you describe the there's something very wrong going on. If this is a Unix or Linux based system and its repeatedly exhibiting this behaviour then the kernel is terminating the script - unless it has been configured not to do so, the kernel will be forcing a core dump of the process.
Either go build a new system to run your code on or Google how to capture and diagnose a core dump on your operating system.
update
If xdebug is reporting the process is still running then it probably hasn't dumped its core, but "not producing output" != "not running". What state is the process in? What happens when you redirect the ouput? What is the end-to-end output channel when it misbehaves?
The problem did not lie directly with my PHP installation or the application itself, but somewhere in my IDE PHPStorm. When running the code with the same PHP interpreter outside of the IDE's wrappers, it all works fine. The procedures described by the many users here helped with that. Thank you.
I work on a PHP project and I use flush().
I did a lot of search and found that PHP sends long outputs of scripts to the browser in chunk parts and does not send all the huge data when the script terminates.
I want to know the size of this data, I mean how many bytes the output must be for PHP to send them to browser.
It's not only PHP that chunks the data; it's actually the job of Apache (or Tomcat etc) to do this. That's why the default is to turn off the "chunking" in PHP and leave it to Apache. Even if you force a flush from PHP, it still can get trapped by Apache. From the manual:
flush() may not be able to override the buffering scheme of your web
server and it has no effect on any client-side buffering in the
browser. It also doesn't affect PHP's userspace output buffering
mechanism. This means you will have to call both ob_flush() and
flush() to flush the ob output buffers if you are using those.
There's a Wikipedia article on transfer encoding / chunking: http://en.wikipedia.org/wiki/Chunked_transfer_encoding
Apache gets more complicated with GZIP or deflate encoding; you'll need to hit an apache server as to how you chan configure it.
i think you are wrong
see this code
echo str_repeat(' ',1024);
for($i=0;$i<10;$i++){
echo $i;
flush();
sleep(1);
if you run it see that every 1 byte sent to browser and print
//the str_repeat is for browser buffer for showing data and nothing else
I wasn't sure how to title this thread, sorry.
I have a script that processes some logs and I echo a lot of debug information as the process goes. Since moving to the new server, it seems that the script hangs for 30 odd seconds, then spits out all the logging, then hangs again for 30 odd seconds and the process continues.
This is really odd behavior and I don't know where to start. Its like it isn't processing the file line by line but in blocks ...
PHP version is 5.1.6 on a CentOS running plesk. (My old CP was CPanel)
Any ideas?
EDIT: Simple example of my issue - Running this code:
for ($i=0; $i<100; $i++) {
echo "test $i";
sleep(1);
}
the script will hang for 100 seconds, then print out all the "test 1" ect. Sleep is required in my main script and on the other server just echoed the values in turn.
EDIT2: Have tried setting output_buffering = 0 and implicit_flush = On and didn't help.
You may have output_buffering On. Try to disable it first.
You can do it either in the php.ini file, in a .htaccess file if your server allows it, or use the following code at the beginning of your PHP script:
while (ob_get_level()) ob_end_clean();
Also, use flush() after each echo or print, and it should be all right!
Update:
You might also encounter other buffers that you cannot control from within PHP (web server, browser, ...), which is why you're still not seing anything. A workaround is to send some blank bytes after each print:
while (ob_get_level()) ob_end_clean();
for ($i=0; $i<100; $i++) {
echo "test $i";
echo str_repeat(' ', 256);
flush();
sleep(1);
}
However, while this example works for me on IE & Firefox, it does not work on Chrome!
I thought flush(); would work, at least from what Google/Stackoverflow tell me, but on my Windows WAMP (Windows, Apache, MySQL, PHP) system it doesn't work.
Is there some PHP setting I have to set to make flush() work?
Here's my code:
<?php
echo "Fun";
flush();
sleep(5);
echo "<br>Mo";
?>
The code just outputs all together when the script is done executing (after 5 seconds).. I don't want this, I want 'Fun' to show up right away, and then after 5 seconds 'Mo'.
I've tried other combinations of flush like ob_end_flush(); or ob_implicit_flush(true); but nothing is working. Any ideas?
So that's what I found out:
Flush would not work under Apache's mod_gzip or Nginx's gzip because, logically, it is gzipping the content, and to do that it must buffer content to gzip it. Any sort of web server gzipping would affect this. In short, at the server side, we need to disable gzip and decrease the fastcgi buffer size. So:
In php.ini:
. output_buffering = Off
. zlib.output_compression = Off
In nginx.conf:
. gzip off;
. proxy_buffering off;
Also have this lines at hand, specially if you don't have acces to php.ini:
#ini_set('zlib.output_compression',0);
#ini_set('implicit_flush',1);
#ob_end_clean();
set_time_limit(0);
Last, if you have it, coment the code bellow:
ob_start('ob_gzhandler');
ob_flush();
PHP test code:
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);
}
The script works fine from CLI, displaying "Fun", waiting 5 secs before displaying "<br>Mo".
For a browser the results might be a bit different because:
The browser wont start rendering right away. Getting 3 bytes of data for HTML document isn't enough to do anything, so it'll most likely wait for a few more.
Implicit IO buffering on the lib level will most likely be active until a newline is received.
To work around 1) use text/plain content type for your test; 2) needs newlines, so do an echo "Fun\n"; and echo "<br>Mo\n"; Of course you wont be using text/plain for real HTML data.
If you're using CGI/FastCGI, forget it! These don't implement flush. The Webserver might have it's own buffer.
You can disable all output buffering in PHP with following command:
ob_implicit_flush();
If the problem persists, although you explicitly set
implicit_flush = yes
in your php.ini, you might also want to set
output_buffering = off
which did the trick in my case (after pulling my hair for 4+hrs)
Check your php.ini for output_buffering.
Maybe the problem is Apache here, which also may have buffers...
PHP Echo or Print functions does not show anything when php is busy with something (like when surfing the web with curl or something like that).
Later i discovered php does show the output when you execute your php on the command line:
php myscript.php
But right now i don't get any outputs from command line too!
Is there any kind of tricks or setting should be done to make php show the outputs?
Chances are, it's caching the results (both in PHP and the web server) and not actually sending them to the browser yet. the best suggestion I can give is this chunk from my code:
/**
* Act as a "breakpoint" in the code, forcing everything to be flushed to the browser
*/
function breakpoint() {
global $debug;
if ($debug) { // So that it doesn't slow down extracts
ob_flush();
flush();
sleep(.1);
}
}
The $debug stuff is if we're running the page in debug mode, specific to our website.
The two main thing you need are ob_flush(), which will send PHP's buffer to the web server's buffer, and flush() which will cause the server to dump to the browser. (Note: if the browser caches before displaying anything, nothing can prevent this) The sleep is there to help make sure it doesn't get overloaded, and has a chance to flush properly.
See:
http://ca.php.net/manual/en/function.ob-flush.php
and
http://ca.php.net/manual/en/function.flush.php
Both PHP and your web server are likely to be caching the output of echo and print. This will often result in no output until the script completes.
Try looking at flush() to force the output out of PHP, but it still may get held up at the web server, so may not help...