|
|
ob_gzhandler (PHP 4 >= 4.0.4, PHP 5) ob_gzhandler --
ob_start callback function to gzip output buffer
Descriptionstring ob_gzhandler ( string buffer, int mode ) Замечание:
ob_gzhandler() requires the zlib
extension.
ob_gzhandler() is intended to be used as a
callback function for ob_start() to help
facilitate sending gz-encoded data to web browsers that support
compressed web pages. Before ob_gzhandler()
actually sends compressed data, it determines what type of
content encoding the browser will accept ("gzip", "deflate" or
none at all) and will return its output accordingly. All
browsers are supported since it's up to the browser to send the
correct header saying that it accepts compressed web pages.
If a browser doesn't support compressed pages this function returns
FALSE.
Замечание:
mode was added in PHP 4.0.5.
Пример 1. ob_gzhandler() example |
<?php
ob_start("ob_gzhandler");
?>
<html>
<body>
<p>This should be a compressed page.</p>
</html>
<body>
|
|
See also
ob_start() and
ob_end_flush().
TheSeoDude
09-Sep-2007 03:34
I wrote a simple script that I use on my site. Bandwidth consumption dropped dramatically. Pages shrunk 3-5 times.
The script simulates the results of using this function directly but by using regular output buffering with ob_start. So you get to output gzip and play with it before you do.
You can find the script with explanations here:
http://www.tellinya.com/art2/106/gzip-compress-html
Cheers and input is always welcome fellow coders!
maratd at gmail dot com
29-Aug-2007 08:51
Someone previously mentioned that MSIE doesn't cache gzipped content. This is false. He misread the source of information. In fact, IE will cache gzipped content no matter what. Here is the quote from the mailing list:
The reason the COMPRESSED responses are, in fact,
always getting cached no matter what "Vary:" field name
is present is just as I suspected... it is because MSIE
decides it MUST cache responses that arrive with
"Content-Encoding: gzip" because it MUST have a
disk ( cache ) file to work with in order to do the
decompression.
Source: http://lists.over.net/pipermail/mod_gzip/2002-December/006826.html
tehjosh at gamingg dot net
01-Aug-2007 04:18
faisun at sina dot com:
If you read up on output buffering, you'll see that if an output buffer callback returns false, this instructs PHP to output the original string untouched. That's why ob_gzhandler() returns false if the encoding is not supported. When ob_start("ob_gzhandler") is used and encoding is not supported, ob_gzhandler() will return false and PHP outputs the original, uncompressed string.
jsnell at e-normous dot com:
Output buffering callback functions accept up to two parameters, so this would probably work better for your situation:
<?php
function ob_gz_handler_no_errors($buffer, $mode)
{
@ob_gzhandler($buffer, $mode);
}
ob_start('ob_gzhandler_no_errors');
?>
However, if you're trying to suppress errors caused by headers already being sent, it would be better to start the output buffering earlier, before any output can be sent.
jsnell at e-normous dot com
31-May-2007 11:04
If you want to suppress errors (such as for cases when headers are already sent) and you don't want to write or patch your error_handler, you need to create an intermediate callback:
function ob_gz_handler_no_errors($buffer)
{
@ob_gzhandler($buffer);
}
ob_start('ob_gzhandler_no_errors');
faisun at sina dot com
23-Apr-2007 09:53
My PHP version is 5.2.1 For windows.
If browser doesn't support compressed ,
ob_start('ob_gzhandler') returns the original string,
but $str = ob_gzhandler ( $buffer, 5 ) returns false;
<?php
ob_start('ob_gzhandler') ;
echo 'This is a string.';
?>
<?php
header("Content-Encoding: gzip");
$buffer = 'This is a string.';
$str = ob_gzhandler ( $buffer, 5 ) ;
if($str===false){
echo 'ob_gzhandler() returns false.';
}else{
echo $str;
}
?>
<?php
echo file_get_contents('http://www.php.net/1.php');
echo file_get_contents('http://www.php.net/2.php');
?>
nicolas dot grekas+php at gmail dot com
28-Jan-2007 10:45
Here are some precisions :
- the "mode" arg accepts a bit field composed of PHP_OUTPUT_HANDLER_START, PHP_OUTPUT_HANDLER_CONT and PHP_OUTPUT_HANDLER_END. See http://www.php.net/manual/fr/ref.zlib.php#56216 for an example. The value that jazfresh recommends below (5) is the good one, because 5 == PHP_OUTPUT_HANDLER_START | PHP_OUTPUT_HANDLER_END.
- when called INSIDE an output buffering handler, ob_gzhandler DOES NOT return false when the browser doesn't support compressed pages. It rather returns the original string.
fpiat at bigfoot dot com
27-Aug-2006 05:55
DON'T compress/gzip your Error pages :
i can think of two good reasons not to compress your error pages:
1. You want to make sure that people can read you error pages, don't you ?
2. Compressing pages have a "side effect" : it's smaller !! if you return "HTTP/1.x 404 Document Not fount" (or any other HTTP error), MSIE will display it's built in error message, not yours if it's small than 513bytes. (see "HOW TO: Turn Off the Internet Explorer 5.x and 6.x 'Show Friendly HTTP Error Messages' Feature on the Server Side" http://support.microsoft.com/default.aspx?scid=kb;en-us;Q294807 )
spam_this at zleelz dot com
26-Aug-2006 11:49
When writing scripts for distribution, I would usually "null" out the following deprecated superglobals so that users who uses the script will not be able to use them.
<?php
$HTTP_GET_VARS = null;
$HTTP_POST_VARS = null;
$HTTP_COOKIE_VARS = null;
$HTTP_POST_FILES = null;
$HTTP_SERVER_VARS = null;
?>
However, when using ob_start('ob_gzhandler'), one of those superglobals somehow disable this function.
Found out that it was $HTTP_SERVER_VARS that's causing the problems.
<?php
ob_start('ob_gzhandler');
$HTTP_GET_VARS = null;
$HTTP_POST_VARS = null;
$HTTP_COOKIE_VARS = null;
$HTTP_POST_FILES = null;
?>
I don't know why it does that, but I just want to point that out.
richard at mf2fm dot com
11-Jul-2006 02:50
According to the manual, if ob_gzhander detects that the browser is unable to support deflate or gzip it returns FALSE. Does this mean that if you use ob_start("ob_gzhandler"), any browsers that do not support gzip/deflate will receive a blank page?
I've been having problems with IE6 displaying gzipped pages and adding a test:
<?php
if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) ob_start("ob_gzhandler");
else ob_start();
?>
solved the problem. Surely if ob_gzhandler detects a lack of support for deflation it should return the input unchanged and not FALSE?
michael at michaelphipps dot com
29-Apr-2006 03:34
It is also possible to use ob_gzhandler to compress css and javascript files, however some browsers such as firefox expect content type text/css on css files.
To get around this send a content type header:
<?php
ob_start('ob_gzhandler');
?>
.... your css content ...
<?php
header("Content-Type: text/css");
header("Content-Length: ".ob_get_length());
ob_end_flush();
?>
mariusads[at]helpedia[dot]com
04-Feb-2006 09:56
Please be aware that, as other users have already mentioned, the compression will fail if there are characters before the php start tag "< ?".
This is also the case when saving files in UTF-8 format with editors such as Ultraedit. Make sure you save the file using the defined option UTF-8 NO BOM or delete the BOM otherwise the two UTF BOM characters will be written at the start of the file.
lapoint2 at msu dot edu
06-Sep-2005 06:40
So why doesn't the web server just do this by default?
This works for me if I do:
ini_set('zlib.output_compression_level', 3); ob_start("ob_gzhandler");
or even just:
ob_start("ob_gzhandler");
I did the level 3 compression, I think the default was 6 and I didn't want to put too much load on the server. For a 895k file (my largest) the compression levels were:
1 = 189k
3 = 178k
4 = 163k
6 = 156k (I believe 6 is the default if you leave out the ini_set)
9 = 155k
I use http://www.whatsmyip.org/mod_gzip_test/ to check the sizes.
FYI: This works with dynamic files in Movable Type 3.x (I'm testing it in 3.2) I've got the above command in the first line of my mtview.php file.
More info here: http://www.whatsmyip.org/forum/viewtopic.php?t=43
On several sites I've read the some browsers don't like compressed CSS.
Tony Piper
14-Jun-2005 07:11
I just spent 30 minutes wondering why my browser wasn't getting the gzipped version :-O
If you're using Google Web Access your pages will be delivered to the browser uncompressed unless you tell GWA to ignore the specific site.
Obvious, really.
24-May-2005 03:27
No matter the circumstances, you MUST NOT check the user agent string to find out if gzip compression is enabled. HTTP defines the Accept-Encoding header for exactly this purpose and you MUST check it before enabling compression.
m at rtij dot nl
16-Apr-2005 05:29
All versions of MSIE have a bug where they don't cache gzipd contents. If your application depends on caching, this is something to keep in mind. In the end, I did:
<?php
if (!isset($use_page_cache))
$use_page_cache = 1;
if (!isset($use_compression))
$use_compression = 1;
$browser="other";
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$agent = $_SERVER['HTTP_USER_AGENT'];
if (eregi("opera",$agent)){
$browser="opera";
}elseif(eregi("msie",$agent)){
$browser="msie";
}
}
if ($use_compression && !( $use_page_cache && $browser == "msie")) {
ob_start('ob_gzhandler');
}
session_cache_limiter("must-revalidate");
session_start();
if ($use_page_cache) {
$hash = md5($content);
$headers = getallheaders();
if (isset($headers['If-None-Match']) && ereg($hash, $headers['If-None-Match']))
{
header('HTTP/1.1 304 Not Modified');
exit;
}
header("ETag: \"$hash\"");
}
print $content;
?>
grange (at) club-internet (dot) fr
07-Mar-2005 07:17
It may seem obvious but if you use ob_start("ob_gzhandler"), make sure no content is unintentionally echo'ed before : this could be blank lines before '<?php' or after '?>' tags in included files or even errors.
Otherwise, only a part of the content (the content sent after ob_start()) will be compressed, which will confuse the client.
Setting compression using zlib.output_compression either in php.ini or in Apache configuration file (with directive php_flag) is safer in this regard.
wallacebw at some-domain dot com
21-Feb-2005 09:50
IE 6+ appears to validate the CRC and disgard invalid gzip content FYI...
Brian
mazsolt at yahoo dot com
18-Mar-2004 07:20
if you want to send an output to the browser (which accepts gzip), and you haven't set the buffering callback ob_start("ob_gzhandler"), you may use the gzencode() function.
header("Content-Encoding: gzip");
echo gzencode("some output", 9, FORCE_GZIP);
daijoubuNOSP at Mvideotron dot ca
27-Oct-2003 02:05
So much code...here's a lighter/faster one:
<?php
if ( $do_gzip_compress )
{
$gzip_size = ob_get_length();
$gzip_contents = ob_get_clean(); echo "\x1f\x8b\x08\x00\x00\x00\x00\x00",
substr(gzcompress($gzip_contents, 9), 0, - 4), pack('V', crc32($gzip_contents)), pack('V', $gzip_size); }
exit;
?>
I wouldn't recommande using level 9, waste of CPU, something between 1 and 6 would be more resonable
I have tested without the substr/crc/size and it worked flawlessly in IE5/5.5/6, Opera7.11/7.21, IE5.5 MAC
brewthatistrue at plzYnoAspamHorOevilO dot com
21-Sep-2003 02:04
i had a LOT of trouble trying to get gzipping working correctly
i kept getting a blank page on the first load, although subsequent pages loaded fine.
i tried stuff with ob_flush and ob_end_clean and all kinds of stuff i didn't understand. i'm totally confused about different versions of php and different methods of gzipping.
in the end, i got it working (maybe i'll understand it later).
i ended up using phpBB's code (stripped of non-gz stuff, and ever-so-slightly modified)
http://phpbb.com/
index.php:
------------
<?php
require_once('top.php');
echo "<html>\n<head>\n<title>Gzip Test</title>\n<body>\n<h1>testing</h1>\n</body>\n</html>";
require_once('bottom.php');
?>
gz_header.php - taken form phpBB's page_header.php
--------------
<?php
$phpver = phpversion();
$useragent = (isset($_SERVER["HTTP_USER_AGENT"]) ) ? $_SERVER["HTTP_USER_AGENT"] : $HTTP_USER_AGENT;
if ( $phpver >= '4.0.4pl1' && ( strstr($useragent,'compatible') || strstr($useragent,'Gecko') ) )
{
if ( extension_loaded('zlib') )
{
ob_start('ob_gzhandler');
}
}
else if ( $phpver > '4.0' )
{
if ( strstr($HTTP_SERVER_VARS['HTTP_ACCEPT_ENCODING'], 'gzip') )
{
if ( extension_loaded('zlib') )
{
$do_gzip_compress = TRUE;
ob_start();
ob_implicit_flush(0);
header('Content-Encoding: gzip');
}
}
}
?>
gz_footer.php - taken form phpBB's page_tail.php
------------
<?php
if ( $do_gzip_compress )
{
$gzip_contents = ob_get_contents();
ob_end_clean();
$gzip_size = strlen($gzip_contents);
$gzip_crc = crc32($gzip_contents);
$gzip_contents = gzcompress($gzip_contents, 9);
$gzip_contents = substr($gzip_contents, 0, strlen($gzip_contents) - 4);
echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
echo $gzip_contents;
echo pack('V', $gzip_crc);
echo pack('V', $gzip_size);
}
exit;
?>
i must admit to not seeing this working in opera 7.11. perhaps i will figure that one out.
if there is anything i should change email me and i can edit my post
jazfresh at SPAM-JAVELIN dot hotmail dot com
18-Sep-2003 07:54
In the set_error_handler notes, there is a technique described for capturing all errors (even parse errors) before they are displayed the user, using a special error handler and output handler. If this output handler detects a fatal error in the output buffer, it's captured and dealt with before it can be displayed to the user. If no error was detected, then output buffer is displayed verbatim (i.e. without being compressed).
If you are using this method, you can still take advantage of ob_gzhandler's compression. However, you MUST specify a mode argument (I'm using 4.2.2 on RedHat9). The mode value affects which headers are automatically added (Content-Encoding, etc). A value of '5' worked for me. '0' or discarding the argument produces a blank screen under Mozilla.
<?php
function my_output_handler(&$buffer) {
if(ereg("(error</b>:)(.+) in <b>(.+)</b> on line <b>(.+)</b>", $buffer, $regs)) {
my_error_handler(E_ERROR, $regs[2], $regs[3], $regs[4]);
return 'An internal error occurred.';
} else {
return ob_gzhandler($buffer, 5);
}
}
?>
daijoubu at videotron dot ca
06-Sep-2003 04:35
About the previous note from Davey:
ob_start(array('ob_gzhandler',9));
Does not work. The output size isn
|
|