Php ob end clean php

Connection handling

When a PHP script is running normally, the NORMAL state is active. If the remote client disconnects, the ABORTED state flag is turned on. A remote client disconnect is usually caused by users hitting their STOP button. If the PHP-imposed time limit (see set_time_limit() ) is hit, the TIMEOUT state flag is turned on.

You can decide whether or not you want a client disconnect to cause your script to be aborted. Sometimes it is handy to always have your scripts run to completion even if there is no remote browser receiving the output. The default behaviour is however for your script to be aborted when the remote client disconnects. This behaviour can be set via the ignore_user_abort php.ini directive as well as through the corresponding php_value ignore_user_abort Apache httpd.conf directive or with the ignore_user_abort() function. If you do not tell PHP to ignore a user abort and the user aborts, your script will terminate. The one exception is if you have registered a shutdown function using register_shutdown_function() . With a shutdown function, when the remote user hits his STOP button, the next time your script tries to output something PHP will detect that the connection has been aborted and the shutdown function is called. This shutdown function will also get called at the end of your script terminating normally, so to do something different in case of a client disconnect you can use the connection_aborted() function. This function will return true if the connection was aborted.

Читайте также:  Php рекурсивный обход всех

Your script can also be terminated by the built-in script timer. The default timeout is 30 seconds. It can be changed using the max_execution_time php.ini directive or the corresponding php_value max_execution_time Apache httpd.conf directive as well as with the set_time_limit() function. When the timer expires the script will be aborted and as with the above client disconnect case, if a shutdown function has been registered it will be called. Within this shutdown function you can check to see if a timeout caused the shutdown function to be called by calling the connection_status() function. This function will return 2 if a timeout caused the shutdown function to be called.

One thing to note is that both the ABORTED and the TIMEOUT states can be active at the same time. This is possible if you tell PHP to ignore user aborts. PHP will still note the fact that a user may have broken the connection, but the script will keep running. If it then hits the time limit it will be aborted and your shutdown function, if any, will be called. At this point you will find that connection_status() returns 3.

User Contributed Notes 12 notes

hey, thanks to arr1, and it is very useful for me, when I need to return to the user fast and then do something else.

When using the codes, it nearly drive me mad and I found another thing that may affect the codes:

This is because the zlib is on and the content will be compressed. But this will not output the buffer until all output is over.

Читайте также:  Machine learning library in python

So, it may need to send the header to prevent this problem.

ob_end_clean ();
header ( «Connection: close\r\n» );
header ( «Content-Encoding: none\r\n» );
ignore_user_abort ( true ); // optional
ob_start ();
echo ( ‘Text user will see’ );
$size = ob_get_length ();
header ( «Content-Length: $size » );
ob_end_flush (); // Strange behaviour, will not work
flush (); // Unless both are called !
ob_end_clean ();

//do processing here
sleep ( 5 );

echo( ‘Text user will never see’ );
//do some processing
?>

Closing the users browser connection whilst keeping your php script running has been an issue since 4.1, when the behaviour of register_shutdown_function() was modified so that it would not automatically close the users connection.

sts at mail dot xubion dot hu
Posted the original solution:

header ( «Connection: close» );
ob_start ();
phpinfo ();
$size = ob_get_length ();
header ( «Content-Length: $size » );
ob_end_flush ();
flush ();
sleep ( 13 );
error_log ( «do something in the background» );
?>

Which works fine until you substitute phpinfo() for
echo (‘text I want user to see’); in which case the headers are never sent!

The solution is to explicitly turn off output buffering and clear the buffer prior to sending your header information.

ob_end_clean ();
header ( «Connection: close» );
ignore_user_abort (); // optional
ob_start ();
echo ( ‘Text the user will see’ );
$size = ob_get_length ();
header ( «Content-Length: $size » );
ob_end_flush (); // Strange behaviour, will not work
flush (); // Unless both are called !
// Do processing here
sleep ( 30 );
echo( ‘Text user will never see’ );
?>

Just spent 3 hours trying to figure this one out, hope it helps someone 🙂

Tested in:
IE 7.5730.11
Mozilla Firefox 1.81

The point mentioned in the last comment isn’t always the case.

If a user’s connection is lost half way through an order processing script is confirming a user’s credit card/adding them to a DB, etc (due to their ISP going down, network trouble. whatever) and your script tries to send back output (such as, «pre-processing order» or any other type of confirmation), then your script will abort — and this could cause problems for your process.

I have an order script that adds data to a InnoDB database (through MySQL) and only commits the transactions upon successful completion. Without ignore_user_abort(), I have had times when a user’s connection dropped during the processing phase. and their card was charged, but they weren’t added to my local DB.

So, it’s always safe to ignore any aborts if you are processing sensitive transactions that should go ahead, whether your user is «watching» on the other end or not.

PHP changes directory on connection abort so code like this will not do what you want:

function abort ()
if( connection_aborted ())
unlink ( ‘file.ini’ );
>
register_shutdown_function ( ‘abort’ );
?>

actually it will delete file in apaches’s root dir so if you want to unlink file in your script’s dir on abort or write to it you have to store directory
function abort ()
global $dsd ;
if( connection_aborted ())
unlink ( $dsd . ‘/file.ini’ );
>
register_shutdown_function ( ‘abort’ );
$dsd = getcwd ();
?>

I had a lot of problems getting a redirect to work, after which my script was intended to keep working in the background. The redirect to another page of my site simply would only work once the original page had finished processing.

I finally found out what was wrong:
The session only gets closed by PHP at the very end of the script, and since access to the session data is locked to prevent more than one page writing to it simultaneously, the new page cannot load until the original processing has finished.

Solution:
Close the session manually when redirecting using session_write_close():

ignore_user_abort ( true );
set_time_limit ( 0 );

$strURL = «PUT YOUR REDIRCT HERE» ;
header ( «Location: $strURL » , true );
header ( «Connection: close» , true );
header ( «Content-Encoding: none\r\n» );
header ( «Content-Length: 0» , true );

sleep ( 100 );
exit;
?>

But careful:
Make sure that your script doesn’t write to the session after session_write_close(), i.e. in your background processing code. That won’t work. Also avoid reading, remember, the next script may already have modified the data.

So try to read out the data you need prior to redirecting.

The CONNECTION_XXX constants that are not listed here for some reason are:

0 = CONNECTION_NORMAL
1 = CONNECTION_ABORTED
2 = CONNECTION_TIMEOUT
3 = CONNECTION_ABORTED & CONNECTION_TIMEOUT

Источник

Смотрите также

It seems that while using output buffering, an included file which calls die() before the output buffer is closed is flushed rather than cleaned. That is, ob_end_flush() is called by default.

// a.php (this file should never display anything)
ob_start ();
include( ‘b.php’ );
ob_end_clean ();
?>

// b.php
print «b» ;
die();
?>

This ends up printing «b» rather than nothing as ob_end_flush() is called instead of ob_end_clean(). That is, die() flushes the buffer rather than cleans it. This took me a while to determine what was causing the flush, so I thought I’d share.

You possibly also want to end your benchmark after the output is flushed.

ob_start ();
for ( $i = 0 ; $i < 5000 ; $i ++)
echo str_repeat ( «your string blablabla bla bla» , ( rand () % 4 ) + 1 ). «
\n» ;

For those who are looking for optimization, try using buffered output.

I noticed that an output function call (i.e echo()) is somehow time expensive. When using buffered output, only one output function call is made and it seems to be much faster.
Try this :

for ( $i = 0 ; $i < 5000 ; $i ++)
echo str_repeat ( «your string blablabla bla bla» , ( rand () % 4 ) + 1 ). «
\n» ;

echo your_benchmark_end_function ();
?>

And then :

ob_start ();
for ( $i = 0 ; $i < 5000 ; $i ++)
echo str_repeat ( «your string blablabla bla bla» , ( rand () % 4 ) + 1 ). «
\n» ;

echo your_benchmark_end_function ();
ob_end_flush ();
?>

Take care to take exceptions in the code in mind when using ob_start and ob_get_contents. If you do not do this, the number of calls to ob_start will not match those to ob_end and you’re not gonna have a good time.

public function requireIntoVariable ( $path ) ob_start ();

try require $path ;
> catch ( Exception $e ) ob_end_clean ();
throw $e ;
>

$output = ob_get_contents ();
ob_end_clean ();
return $output ;
>
?>

Sometimes you might not want to include a php-file under the specifications defined in the functions include() or require(), but you might want to have in return the string that the script in the file «echoes».

Include() and require() both directly put out the evaluated code.

For avoiding this, try output-buffering:
ob_start ();
eval( file_get_contents ( $file ));
$result = ob_get_contents ();
ob_end_clean ();
?>
or
ob_start ();
include( $file );
$result = ob_get_contents ();
ob_end_clean ();
?>
which i consider the same, correct me if I’m wrong.

Best regards, BasicArtsStudios

I ran out of memory, while output buffering and drawing text on imported images. Only the top portion of the 5MP image was displayed by the browser. Try increasing the memory limit in either the php.ini file( memory_limit = 16M; ) or in the .htaccess file( php_value memory_limit «16M» ). Also see function memory_get_usage() .

Sometimes users are blaming about slow pages . not being aware that mostly this is due to network issues.
So I’ve decided to add some statistics at the end of my pages:

At beginning I start the counters:

function microtime_float () <
if ( version_compare ( PHP_VERSION , ‘5.0.0’ , ‘>’ )) return microtime ( true );
list( $u , $s )= explode ( ‘ ‘ , microtime ()); return ((float) $u +(float) $s );
>
$initime = microtime_float ();
ob_start ();
ob_implicit_flush ();
?>

And at the end I show the statistics:

echo «PHP Time: » . round (( microtime_float ()- $initime )* 1000 ). » msecs. » ;
echo «Size: » . round_byte ( strlen ( ob_get_contents ()));
ob_end_flush ();
?>

(round_byte is my function to print byte sizes)

Output buffering is set to ‘4096’ instead of ‘Off’ or ‘0’ by default in the php-5.0.4-10.5 RPM for Fedora Core release 4 (Stentz). This has cost me much time!

Now this just blew my mind. I had a problem with MySQL being incredibly slow on Windows 2003 running IIS. on ASP/VBScript pages. PHP is also installed on the server and so is Microsoft SQL 2005 Express. (Yes, we’re running ASP, PHP, MySQL and MS SQL on the same Windows 2003 Server using IIS.)

I was browsing the internet for a solution and saw a suggestion that I change output_buffering to on if MySQL was slow for PHP pages. Since we also served PHP pages with MySQL from the same server, it caught my eye. For the hell of it, I went into php.ini and changed output_buffering to on and suddenly MySQL and ASP was faster. MySQL and PHP was faster. Microsoft SQL Server 2005 Express and ASP was faster. everything was faster. even stuff that had no PHP!

And I didn’t even have to restart IIS. As soon as I saved the php.ini file with the change, everything got faster.

Apparently PHP and MySQL and IIS are so intertwined somehow that changing the buffering setting really effects the performance of the entire server.

So, if you are having performance problems on Windows 2003 & IIS, you might try setting output_buffering = On in php.ini if you happen to have PHP installed. Having it set to off apparently effects the performance of Windows 2003 and IIS severely. even for webpages that do not use PHP or MySQL.

Unfortunately, the PHP guys didn’t build support into any of the image output functions to return the image instead of outputting it.

Fortunately, we have output buffering to fix that.

$im = imagecreatetruecolor ( 200 , 200 );

// Other image functions here.

ob_start ();
imagepng ( $im );
$imageData = ob_get_contents ();
ob_clean ();

?>

You can now use the $imageData variable to either create another GD image, save it, put it in a database, make modifications to the binary, or output it to the user. You can easily check the size of it as well without having to access the disk. just use strlen();

Источник

Оцените статью