[ Index ]
 

Code source de Typo3 4.1.3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/t3lib/ -> class.gzip_encode.php (source)

   1  <?php
   2  /**
   3   * News: I had once said that when PHP 4.0.5 comes out I will reccomend the built in
   4   * ob_gzhandler over my code unless you are generating flash or images on the fly.
   5   *
   6   * I was wrong. PHP 4.0.5 is out and ob_gzhandler doesn't work for me.
   7   *
   8   * Note: This is rather cool: http://leknor.com/code/gziped.php
   9   * It will calculate the effects of this class on a page.
  10   * compression level, cpu time, download time, etc
  11   *
  12   * Note: this may be better for some sites:
  13   * http://www.remotecommunications.com/apache/mod_gzip/
  14   * I've read that the above doesn't work with PHP output.
  15   *
  16   * Changes compared to the upstream version:
  17   *
  18   * 2007-03-27  Oliver Hader  <oh@inpublica.de>
  19   *  - Fixed bug #4623: Content encoding with x-gzip not allowed
  20   *  - Fixed missing comments and line formats (cleaner)
  21   * 2005-12-09  Peter Niederlag  <peter@niederlag.de>
  22   *    - Fixed bug #1976: PHP5 type-conversion of string 'true' and boolean
  23   *
  24   * $Id: class.gzip_encode.php 2371 2007-07-02 15:55:46Z ohader $
  25   *
  26   * @author    Sandy McArthur, Jr. <leknor@leknor.com>
  27   */
  28  /**
  29   * [CLASS/FUNCTION INDEX of SCRIPT]
  30   *
  31   *
  32   *
  33   *   53: class gzip_encode
  34   *  193:     function gzip_encode($level = 3, $debug=false, $outputCompressedSizes=false)
  35   *  268:     function gzip_accepted()
  36   *  317:     function get_complevel()
  37   *  342:     function linux_loadavg()
  38   *  363:     function freebsd_loadavg()
  39   *
  40   * TOTAL FUNCTIONS: 5
  41   * (This index is automatically created/updated by the extension "extdeveval")
  42   *
  43   */
  44  
  45  
  46  
  47  /**
  48   * gzip_encode - a class to gzip encode php output
  49   *
  50   * @author        Sandy McArthur, Jr. <Leknor@Leknor.com>
  51   * @package        TYPO3
  52   * @subpackage    t3lib
  53   */
  54  class gzip_encode {
  55      /**
  56       * gzip_encode - a class to gzip encode php output
  57       *
  58       * By Sandy McArthur, Jr. <Leknor@Leknor.com>
  59       *
  60       * Copyright 2001 (c) All Rights Reserved, All Responsibility Yours.
  61       * One very slight modification 2005 for PHP5 compatibility reasons for TYPO3 port by Peter Niederlag
  62       *
  63       * This code is released under the GNU LGPL Go read it over here:
  64       * http://www.gnu.org/copyleft/lesser.html
  65       *
  66       * I do make one optional request, I would like an account on or a
  67       * copy of where this code is used. If that is not possible then
  68       * an email would be cool.
  69       *
  70       * How to use:
  71       * 1. Output buffering has to be turned on. You can do this with ob_start()
  72       *    <http://php.net/manual/function.ob-start.php> or in the php config
  73       *    file. Nothing bad happens if output buffering isn't turned on, your
  74       *    page just won't get compressed.
  75       * 2. Include the class file.
  76       * 3. At the _very_ end of your script create an instance of the encode
  77       *    class.
  78       *
  79       * eg:
  80       *    ------------Start of file----------
  81       *    |<?php
  82       *    | ob_start();
  83       *    | include('class.gzip_encode.php');
  84       *    |?>
  85       *    |<HTML>
  86       *    |... the page ...
  87       *    |</HTML>
  88       *    |<?php
  89       *    | new gzip_encode();
  90       *    |?>
  91       *    -------------End of file-----------
  92       *
  93       * Things to note:
  94       * 1. There is no space before the beginning of the file and the '<?php ' tag
  95       * 2. The ob_start() line is optional if output buffering is turned on in
  96       *    the main config file.
  97       * 3. Turning on and off output buffering just won't work.
  98       * 4. There must be nothing after the last '?>' tag at the end of the file.
  99       *    Be careful of a space hiding there.
 100       * 5. There are better ways to compress served content but I think this is
 101       *    the only way to compress php output.
 102       * 6. Your auto_prepend_file is a good place for the ob_start() and
 103       *    your auto_append_file is a good place for new gzip_encode().
 104       * 7. If you put new gzip_encode() in your auto.append file then you can
 105       *    call ob_end_flush() in your script to disable compression.
 106       *
 107       * This was written from scratch from info freely available on the web.
 108       *
 109       * These site(s) were useful to me:
 110       *    http://www.php.net/manual/
 111       *    http://www.ietf.org/rfc/rfc2616.txt (Sections: 3.5, 14.3, 14.11)
 112       *
 113       * Requirments:
 114       *    PHP 4.0.1+:    I use the '===' operator, and output buffering, crc32();
 115       *    zlib:        Needed for the gzip encoding. (Odds are you have it)
 116       *
 117       * Benchmarks:
 118       *    Take a look at http://Leknor.com/code/gziped.php and feed it a page to
 119       *    get an idea of how it will preform on your data or page.
 120       *
 121       * To Do:
 122       * 1. I have reports of no content errors. I can't seem to duplicate this.
 123       *    Please visit my discussion boards if you think you may be able to help
 124       * 2. The Accept-Encoding isn't handled to spec. Check out 14.3 in RFC 2616
 125       *    to see how it should be done.
 126       *
 127       * Change Log:
 128       *    0.66:    Big bug fix. It wouldn't compress when it should.
 129       *    0.65:    Fix for PHP-4.0.5 suddenly removing the connection_timeout() function.
 130       *    0.62:    Fixed a typo
 131       *    0.61:    Detect file types more like described in the magic number files, also
 132       *        added detection for gzip and pk zip files.
 133       *    0.6:    Detect common file types that shouldn't be compressed, mainly
 134       *        for images and swf (Shockwave Flash doesn't really accept gzip)
 135       *    0.53:    Made gzip_accepted() method so everyone can detect if a page
 136       *        will be gzip'ed with ease.
 137       *    0.52:    Detection and graceful handling of improper install/missing libs
 138       *    0.51:    Added FreeBSD load average detection.
 139       *    0.5:    Passing true as the first parameter will try to calculate the
 140       *        compression level from the server's load average. Passing true
 141       *        as the second parameter will turn on debugging.
 142       *    0.4:    No longer uses a temp file to compress the output. Should speed
 143       *        thing up a bit and reduce wear on your hard disk. Also test if
 144       *        the http headers have been sent.
 145       *    0.31:    Made a small change to the tempnam() line to hopefully be more
 146       *        portable.
 147       *    0.3:    Added code for the 'x-gzip'. This is untested, I don't know of
 148       *        any browser that uses it but the RFC said to look out for it.
 149       *    0.2:    Checks for 'gzip' in the Accept-Encoding header
 150       *    0.1:    First working version.
 151       *
 152       * Thanks To (Suggestions and stuff):
 153       *    ?@boas.anthro.mnsu.edu    http://php.net/manual/function.gzcompress.php
 154       *    Kaoslord        <kaoslord@chaos-productions.com>
 155       *    Michael R. Gile        <gilem@wsg.net>
 156       *    Christian Hamm        <chh@admaster.de>
 157       *
 158       * The most recent version is available at:
 159       *    http://Leknor.com/code/
 160       *
 161       */
 162  
 163      var $_version = 0.66; // Version of the gzip_encode class
 164  
 165      var $level;        // Compression level
 166      var $encoding;    // Encoding type
 167      var $crc;        // crc of the output
 168      var $size;        // size of the uncompressed content
 169      var $gzsize;    // size of the compressed content
 170  
 171      /**
 172       * gzip_encode constructor - gzip encodes the current output buffer
 173       * if the browser supports it.
 174       *
 175       * Note: all arguments are optionial.
 176       *
 177       * You can specify one of the following for the first argument:
 178       *     0:    No compression
 179       *     1:    Min compression
 180       *     ...    Some compression (integer from 1 to 9)
 181       *     9:    Max compression
 182       *     true:    Determin the compression level from the system load. The
 183       *         higher the load the less the compression.
 184       *
 185       * You can specify one of the following for the second argument:
 186       *     true:    Don't actully output the compressed form but run as if it
 187       *         had. Used for debugging.
 188       *
 189       * @param    integer        $level: Define the level of compression between 0 (none) and 9 (best compression)
 190       * @param    boolean        $debug: If true, no data will be outputted (default: false)
 191       * @param    boolean        $outputCompressedSizes: If true, the original and compressed size appended as HTML (default: false)
 192       * @return    void
 193       */
 194  	function gzip_encode($level=3, $debug=false, $outputCompressedSizes=false) {
 195          if (!function_exists('gzcompress')) {
 196              trigger_error('gzcompress not found, ' .
 197                  'zlib needs to be installed for gzip_encode',
 198                  E_USER_WARNING);
 199              return;
 200          }
 201          if (!function_exists('crc32')) {
 202              trigger_error('crc32() not found, ' .
 203                  'PHP >= 4.0.1 needed for gzip_encode', E_USER_WARNING);
 204              return;
 205          }
 206          if (headers_sent()) return;
 207          if (connection_status() !== 0) return;
 208          $encoding = $this->gzip_accepted();
 209          if (!$encoding) return;
 210          $this->encoding = $encoding;
 211  
 212          if (strtolower($level) == 'true' || $level === true) {
 213              $level = $this->get_complevel();
 214          }
 215          $this->level = $level;
 216  
 217          $contents = ob_get_contents();
 218          if ($contents === false) return;
 219  
 220          $gzdata = "\x1f\x8b\x08\x00\x00\x00\x00\x00"; // gzip header
 221  
 222              // By Kasper Skaarhoj, start
 223          if ($outputCompressedSizes)    {
 224              $contents.=chr(10)."<!-- Compressed, level ".$level.", original size was ".strlen($contents)." bytes. New size is ".strlen(gzcompress($contents, $level))." bytes -->";
 225              $size = strlen($contents);    // Must set again!
 226          }
 227              // By Kasper Skaarhoj, end
 228  
 229          $size = strlen($contents);
 230          $crc = crc32($contents);
 231          $gzdata .= gzcompress($contents, $level);
 232          $gzdata = substr($gzdata, 0, strlen($gzdata) - 4); // fix crc bug
 233          $gzdata .= pack("V",$crc) . pack("V", $size);
 234  
 235          $this->size = $size;
 236          $this->crc = $crc;
 237          $this->gzsize = strlen($gzdata);
 238  
 239          if ($debug) {
 240              return;
 241          }
 242  
 243          ob_end_clean();
 244          Header('Content-Encoding: ' . $encoding);
 245          Header('Content-Length: ' . strlen($gzdata));
 246          Header('X-Content-Encoded-By: class.gzip_encode '.$this->_version);
 247  
 248          echo $gzdata;
 249      }
 250  
 251  
 252      /**
 253       * gzip_accepted() - Test headers for Accept-Encoding: gzip
 254       * Returns: if proper headers aren't found: false
 255       *          if proper headers are found: 'gzip' or 'x-gzip'
 256       *
 257       * Tip: using this function you can test if the class will gzip the output
 258       *  without actually compressing it yet, eg:
 259       *    if (gzip_encode::gzip_accepted()) {
 260       *       echo "Page will be gziped";
 261       *    }
 262       *  note the double colon syntax, I don't know where it is documented but
 263       *  somehow it got in my brain.
 264       *
 265       * @return    mixed        Returns 'gzip' if the client browser accepts gzip encoding, otherwise false
 266       */
 267  	function gzip_accepted() {
 268              // Checks, if the accepted encoding supports gzip or x-gzip.
 269              // Furthermore a qvalue check is done. "gzip;q=0" means no gzip accepted at all.
 270          $acceptEncoding = t3lib_div::getIndpEnv('HTTP_ACCEPT_ENCODING');
 271          if (preg_match('/(^|,\s*)(x-)?gzip(;q=(\d(\.\d+)?))?(,|$)/i', $acceptEncoding, $match) && ($match[4] === '' || $match[4] > 0)) {
 272              $encoding = 'gzip';
 273          } else {
 274              return false;
 275          }
 276  
 277              // Test file type. I wish I could get HTTP response headers.
 278          $magic = substr(ob_get_contents(),0,4);
 279          if (substr($magic,0,2) === '^_') {
 280              // gzip data
 281              $encoding = false;
 282          } else if (substr($magic,0,3) === 'GIF') {
 283              // gif images
 284              $encoding = false;
 285          } else if (substr($magic,0,2) === "\xFF\xD8") {
 286              // jpeg images
 287              $encoding = false;
 288          } else if (substr($magic,0,4) === "\x89PNG") {
 289              // png images
 290              $encoding = false;
 291          } else if (substr($magic,0,3) === 'FWS') {
 292              // Don't gzip Shockwave Flash files. Flash on windows incorrectly
 293              // claims it accepts gzip'd content.
 294              $encoding = false;
 295          } else if (substr($magic,0,2) === 'PK') {
 296              // pk zip file
 297              $encoding = false;
 298          }
 299  
 300          return $encoding;
 301      }
 302  
 303      /**
 304       * get_complevel() - The level of compression we should use.
 305       *
 306       * Returns an int between 0 and 9 inclusive.
 307       *
 308       * Tip: $gzleve = gzip_encode::get_complevel(); to get the compression level
 309       *      that will be used with out actually compressing the output.
 310       *
 311       * Help: if you use an OS other then linux please send me code to make
 312       * this work with your OS - Thanks
 313       *
 314       * @return    integer        Suggests a level of compression (0..9) for the current situation
 315       */
 316      function get_complevel() {
 317          $uname = posix_uname();
 318          switch ($uname['sysname']) {
 319              case 'Linux':
 320                  $cl = (1 - $this->linux_loadavg()) * 10;
 321                  $level = (int)max(min(9, $cl), 0);
 322              break;
 323              case 'FreeBSD':
 324                  $cl = (1 - $this->freebsd_loadavg()) * 10;
 325                  $level = (int)max(min(9, $cl), 0);
 326                  break;
 327                  default:
 328                  $level = 3;
 329              break;
 330          }
 331          return $level;
 332      }
 333  
 334      /**
 335       * linux_loadavg() - Gets the max() system load average from /proc/loadavg
 336       *
 337       * The max() Load Average will be returned
 338       *
 339       * @return    float        Returns the current load average
 340       */
 341  	function linux_loadavg() {
 342          $buffer = "0 0 0";
 343          $f = fopen("/proc/loadavg","rb");
 344          if (!feof($f)) {
 345              $buffer = fgets($f, 1024);
 346          }
 347          fclose($f);
 348          $load = explode(" ",$buffer);
 349          return max((float)$load[0], (float)$load[1], (float)$load[2]);
 350      }
 351  
 352      /**
 353       * freebsd_loadavg() - Gets the max() system load average from uname(1)
 354       *
 355       * The max() Load Average will be returned
 356       *
 357       * I've been told the code below will work on solaris too, anyone wanna
 358       * test it?
 359       *
 360       * @return    float        Returns the current load average
 361       */
 362  	function freebsd_loadavg() {
 363          $buffer= `uptime`;
 364          $load = array();
 365          ereg("averag(es|e): ([0-9][.][0-9][0-9]), ([0-9][.][0-9][0-9]), ([0-9][.][0-9][0-9]*)", $buffer, $load);
 366  
 367          return max((float)$load[2], (float)$load[3], (float)$load[4]);
 368      }
 369  }
 370  
 371  ?>


Généré le : Sun Nov 25 17:13:16 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics