Documentation TYPO3 par Ameos

class.gzip_encode.php

00001 <?php
00002 
00003 // News: I had once said that when PHP4.0.5 comes out I will reccomend the built in
00004 // ob_gzhandler over my code unless you are generating flash or images on the fly.
00005 //
00006 // I was wrong. PHP4.0.5 is out and ob_gzhandler doesn't work for me.
00007 
00008 // Note: This is rather cool: http://Leknor.com/code/gziped.php
00009 // It will calculate the effects of this class on a page.
00010 // compression level, cpu time, download time, etc
00011 
00012 // Note: this may better for some sites:
00013 // http://www.remotecommunications.com/apache/mod_gzip/
00014 // I've read that the above doesn't work with php output.
00015 
00016 class gzip_encode {
00017     /*
00018      * gzip_encode - a class to gzip encode php output
00019      *
00020      * By Sandy McArthur, Jr. <Leknor@Leknor.com>
00021      *
00022      * Copyright 2001 (c) All Rights Reserved, All Responsibility Yours.
00023      *
00024      * This code is released under the GNU LGPL Go read it over here:
00025      * http://www.gnu.org/copyleft/lesser.html
00026      *
00027      * I do make one optional request, I would like an account on or a
00028      * copy of where this code is used. If that is not possible then
00029      * an email would be cool.
00030      *
00031      * How to use:
00032      * 1. Output buffering has to be turned on. You can do this with ob_start()
00033      *    <http://php.net/manual/function.ob-start.php> or in the php config
00034      *    file. Nothing bad happens if output buffering isn't turned on, your
00035      *    page just won't get compressed.
00036      * 2. Include the class file.
00037      * 3. At the _very_ end of your script create an instance of the encode
00038      *    class.
00039      *
00040      * eg:
00041      *  ------------Start of file----------
00042      *  |<?php
00043      *  | ob_start();
00044      *  | include('class.gzip_encode.php');
00045      *  |?>
00046      *  |<HTML>
00047      *  |... the page ...
00048      *  |</HTML>
00049      *  |<?php
00050      *  | new gzip_encode();
00051      *  |?>
00052      *  -------------End of file-----------
00053      *
00054      * Things to note:
00055      * 1. There is no space before the beginning of the file and the '<?php ' tag
00056      * 2. The ob_start() line is optional if output buffering is turned on in
00057      *    the main config file.
00058      * 3. Turning on and off output buffering just won't work.
00059      * 4. There must be nothing after the last '?>' tag at the end of the file.
00060      *    Be careful of a space hiding there.
00061      * 5. There are better ways to compress served content but I think this is
00062      *    the only way to compress php output.
00063      * 6. Your auto_prepend_file is a good place for the ob_start() and
00064      *    your auto_append_file is a good place for new gzip_encode().
00065      * 7. If you put new gzip_encode() in your auto.append file then you can
00066      *    call ob_end_flush() in your script to disable compression.
00067      *
00068      * This was written from scratch from info freely available on the web.
00069      *
00070      * These site(s) were useful to me:
00071      *  http://www.php.net/manual/
00072      *  http://www.ietf.org/rfc/rfc2616.txt (Sections: 3.5, 14.3, 14.11)
00073      *
00074      * Requirments:
00075      *  PHP 4.0.1+:     I use the '===' operator, and output buffering, crc32();
00076      *  zlib:           Needed for the gzip encoding. (Odds are you have it)
00077      *
00078      * Benchmarks:
00079      *  Take a look at http://Leknor.com/code/gziped.php and feed it a page to
00080      *  get an idea of how it will preform on your data or page.
00081      *
00082      * To Do:
00083      * 1. I have reports of no content errors. I can't seem to duplicate this.
00084      *    Please visit my discussion boards if you think you may be able to help
00085      * 2. The Accept-Encoding isn't handled to spec. Check out 14.3 in RFC 2616
00086      *    to see how it should be done.
00087      *
00088      * Change Log:
00089      *  0.66:   Big bug fix. It wouldn't compress when it should.
00090      *  0.65:   Fix for PHP-4.0.5 suddenly removing the connection_timeout() function.
00091      *  0.62:   Fixed a typo
00092      *  0.61:   Detect file types more like described in the magic number files, also
00093      *          added detection for gzip and pk zip files.
00094      *  0.6:    Detect common file types that shouldn't be compressed, mainly
00095      *          for images and swf (Shockwave Flash doesn't really accept gzip)
00096      *  0.53:   Made gzip_accepted() method so everyone can detect if a page
00097      *          will be gzip'ed with ease.
00098      *  0.52:   Detection and graceful handling of improper install/missing libs
00099      *  0.51:   Added FreeBSD load average detection.
00100      *  0.5:    Passing true as the first parameter will try to calculate the
00101      *          compression level from the server's load average. Passing true
00102      *          as the second parameter will turn on debugging.
00103      *  0.4:    No longer uses a temp file to compress the output. Should speed
00104      *          thing up a bit and reduce wear on your hard disk. Also test if
00105      *          the http headers have been sent.
00106      *  0.31:   Made a small change to the tempnam() line to hopefully be more
00107      *          portable.
00108      *  0.3:    Added code for the 'x-gzip'. This is untested, I don't know of
00109      *          any browser that uses it but the RFC said to look out for it.
00110      *  0.2:    Checks for 'gzip' in the Accept-Encoding header
00111      *  0.1:    First working version.
00112      *
00113      * Thanks To (Suggestions and stuff):
00114      *  ?@boas.anthro.mnsu.edu  http://php.net/manual/function.gzcompress.php
00115      *  Kaoslord                <kaoslord@chaos-productions.com>
00116      *  Michael R. Gile         <gilem@wsg.net>
00117      *  Christian Hamm          <chh@admaster.de>
00118      *
00119      * The most recent version is available at:
00120      *  http://Leknor.com/code/
00121      *
00122      */
00123 
00124     var $_version = 0.66; // Version of the gzip_encode class
00125 
00126     var $level;         // Compression level
00127     var $encoding;      // Encoding type
00128     var $crc;           // crc of the output
00129     var $size;          // size of the uncompressed content
00130     var $gzsize;        // size of the compressed content
00131 
00132     /*
00133      * gzip_encode constructor - gzip encodes the current output buffer
00134      * if the browser supports it.
00135      *
00136      * Note: all arguments are optionial.
00137      *
00138      * You can specify one of the following for the first argument:
00139      *  0:      No compression
00140      *  1:      Min compression
00141      *  ...     Some compression (integer from 1 to 9)
00142      *  9:      Max compression
00143      *  true:   Determin the compression level from the system load. The
00144      *          higher the load the less the compression.
00145      *
00146      * You can specify one of the following for the second argument:
00147      *  true:   Don't actully output the compressed form but run as if it
00148      *          had. Used for debugging.
00149      */
00150     function gzip_encode($level = 3, $debug = false, $outputCompressedSizes=0) {
00151         if (!function_exists('gzcompress')) {
00152             trigger_error('gzcompress not found, ' .
00153                     'zlib needs to be installed for gzip_encode',
00154                     E_USER_WARNING);
00155             return;
00156         }
00157         if (!function_exists('crc32')) {
00158             trigger_error('crc32() not found, ' .
00159                     'PHP >= 4.0.1 needed for gzip_encode', E_USER_WARNING);
00160             return;
00161         }
00162         if (headers_sent()) return;
00163         if (connection_status() !== 0) return;
00164         $encoding = $this->gzip_accepted();
00165         if (!$encoding) return;
00166         $this->encoding = $encoding;
00167 
00168         if ($level === true) {
00169             $level = $this->get_complevel();
00170         }
00171         $this->level = $level;
00172 
00173         $contents = ob_get_contents();
00174         if ($contents === false) return;
00175 
00176         $gzdata = "\x1f\x8b\x08\x00\x00\x00\x00\x00"; // gzip header
00177 
00178                 // By Kasper Skaarhoj, start
00179         if ($outputCompressedSizes)     {
00180                 $contents.=chr(10)."<!-- Compressed, level ".$level.", original size was ".strlen($contents)." bytes. New size is ".strlen(gzcompress($contents, $level))." bytes -->";
00181                 $size = strlen($contents);      // Must set again!
00182         }
00183                 // By Kasper Skaarhoj, end
00184 
00185         $size = strlen($contents);
00186         $crc = crc32($contents);
00187         $gzdata .= gzcompress($contents, $level);
00188         $gzdata = substr($gzdata, 0, strlen($gzdata) - 4); // fix crc bug
00189         $gzdata .= pack("V",$crc) . pack("V", $size);
00190 
00191         $this->size = $size;
00192         $this->crc = $crc;
00193         $this->gzsize = strlen($gzdata);
00194 
00195         if ($debug) {
00196             return;
00197         }
00198 
00199         ob_end_clean();
00200         Header('Content-Encoding: ' . $encoding);
00201         Header('Content-Length: ' . strlen($gzdata));
00202         Header('X-Content-Encoded-By: class.gzip_encode '.$this->_version);
00203 
00204         echo $gzdata;
00205     }
00206 
00207 
00208     /*
00209      * gzip_accepted() - Test headers for Accept-Encoding: gzip
00210      *
00211      * Returns: if proper headers aren't found: false
00212      *          if proper headers are found: 'gzip' or 'x-gzip'
00213      *
00214      * Tip: using this function you can test if the class will gzip the output
00215      *  without actually compressing it yet, eg:
00216      *    if (gzip_encode::gzip_accepted()) {
00217      *       echo "Page will be gziped";
00218      *    }
00219      *  note the double colon syntax, I don't know where it is documented but
00220      *  somehow it got in my brain.
00221      */
00222     function gzip_accepted() {
00223         if (strpos(getenv("HTTP_ACCEPT_ENCODING"), 'gzip') === false) return false;
00224         if (strpos(getenv("HTTP_ACCEPT_ENCODING"), 'x-gzip') === false) {
00225             $encoding = 'gzip';
00226         } else {
00227             $encoding = 'x-gzip';
00228         }
00229 
00230         // Test file type. I wish I could get HTTP response headers.
00231         $magic = substr(ob_get_contents(),0,4);
00232         if (substr($magic,0,2) === '^_') {
00233             // gzip data
00234             $encoding = false;
00235         } else if (substr($magic,0,3) === 'GIF') {
00236             // gif images
00237             $encoding = false;
00238         } else if (substr($magic,0,2) === "\xFF\xD8") {
00239             // jpeg images
00240             $encoding = false;
00241         } else if (substr($magic,0,4) === "\x89PNG") {
00242             // png images
00243             $encoding = false;
00244         } else if (substr($magic,0,3) === 'FWS') {
00245             // Don't gzip Shockwave Flash files. Flash on windows incorrectly
00246             // claims it accepts gzip'd content.
00247             $encoding = false;
00248         } else if (substr($magic,0,2) === 'PK') {
00249             // pk zip file
00250             $encoding = false;
00251         }
00252 
00253         return $encoding;
00254     }
00255 
00256     /*
00257      * get_complevel() - The level of compression we should use.
00258      *
00259      * Returns an int between 0 and 9 inclusive.
00260      *
00261      * Tip: $gzleve = gzip_encode::get_complevel(); to get the compression level
00262      *      that will be used with out actually compressing the output.
00263      *
00264      * Help: if you use an OS other then linux please send me code to make
00265      * this work with your OS - Thanks
00266      */
00267     function get_complevel() {
00268         $uname = posix_uname();
00269         switch ($uname['sysname']) {
00270             case 'Linux':
00271                 $cl = (1 - $this->linux_loadavg()) * 10;
00272                 $level = (int)max(min(9, $cl), 0);
00273                 break;
00274             case 'FreeBSD':
00275                 $cl = (1 - $this->freebsd_loadavg()) * 10;
00276                 $level = (int)max(min(9, $cl), 0);
00277                 break;
00278             default:
00279                 $level = 3;
00280                 break;
00281         }
00282         return $level;
00283     }
00284 
00285     /*
00286      * linux_loadavg() - Gets the max() system load average from /proc/loadavg
00287      *
00288      * The max() Load Average will be returned
00289      */
00290     function linux_loadavg() {
00291         $buffer = "0 0 0";
00292         $f = fopen("/proc/loadavg","rb");
00293         if (!feof($f)) {
00294             $buffer = fgets($f, 1024);
00295         }
00296         fclose($f);
00297         $load = explode(" ",$buffer);
00298         return max((float)$load[0], (float)$load[1], (float)$load[2]);
00299     }
00300 
00301     /*
00302      * freebsd_loadavg() - Gets the max() system load average from uname(1)
00303      *
00304      * The max() Load Average will be returned
00305      *
00306      * I've been told the code below will work on solaris too, anyone wanna
00307      * test it?
00308      */
00309     function freebsd_loadavg() {
00310         $buffer= `uptime`;
00311         ereg("averag(es|e): ([0-9][.][0-9][0-9]), ([0-9][.][0-9][0-9]), ([0-9][.][0-9][0-9]*)", $buffer, $load);
00312 
00313         return max((float)$load[2], (float)$load[3], (float)$load[4]);
00314     }
00315 }
00316 
00317 ?>


Généré par L'expert TYPO3 avec  doxygen 1.4.6