Documentation TYPO3 par Ameos

class.gzip_encode.php

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


Généré par Le spécialiste TYPO3 avec  doxygen 1.4.6