2 // +----------------------------------------------------------------------+
4 // +----------------------------------------------------------------------+
5 // | Copyright (c) 1997-2003 The PHP Group |
6 // +----------------------------------------------------------------------+
7 // | This source file is subject to version 2.0 of the PHP license, |
8 // | that is bundled with this package in the file LICENSE, and is |
9 // | available at through the world-wide-web at |
10 // | http://www.php.net/license/2_02.txt. |
11 // | If you did not receive a copy of the PHP license and are unable to |
12 // | obtain it through the world-wide-web, please send a note to |
13 // | license@php.net so we can mail you a copy immediately. |
14 // +----------------------------------------------------------------------+
15 // | Authors: Ulf Wendel <ulf.wendel@phpdoc.de> |
16 // | Christian Stocker <chregu@phant.ch> |
17 // +----------------------------------------------------------------------+
19 require_once 'lib/pear/Cache/Output.php';
22 * Cache using Output Buffering and contnet (gz) compression.
25 * // place this somewhere in a central config file
26 * define(CACHE_STORAGE_CLASS, 'file');
27 * // file storage needs a dir to put the cache files
28 * define(CACHE_DIR, '/var/tmp/');
30 * // get a cache object
31 * $cache = new Cache_Output(CACHE_STORAGE_CLASS, array('cache_dir' => CACHE_DIR));
33 * if (!($content = $cache->start($cache->generateID($REQUEST_URI)))) {
34 * print "hello world";
35 * $cache->endPrint(+1000);
38 * $cache->printContent();
43 * if (($content = $cache->start($cache->generateID($REQUEST_URI)))) {
44 * $cache->printContent();
47 * print "hello world";
48 * $cache->endPrint(+1000);
51 * Based upon a case study from Christian Stocker and inspired by jpcache.
53 * @version $Id: OutputCompression.php 178289 2005-01-26 09:47:28Z dufuz $
54 * @author Ulf Wendel <ulf.wendel@phpdoc.de>, Christian Stocker <chregu@phant.ch>
58 class Cache_OutputCompression extends Cache_Output
62 * Encoding, what the user (its browser) of your website accepts
64 * "auto" stands for test using $_SERVER['HTTP_ACCEPT_ENCODING']($HTTP_ACCEPT_ENCODING).
67 * @see Cache_OutputCompression(), setEncoding()
69 var $encoding = 'auto';
73 * Method used for compression
78 var $compression = '';
82 * Sets the storage details and the content encoding used (if not autodetection)
84 * @param string Name of container class
85 * @param array Array with container class options
86 * @param string content encoding mode - auto => test which encoding the user accepts
88 function __construct($container, $container_options = '', $encoding = 'auto')
90 $this->setEncoding($encoding);
91 parent::__construct($container, $container_options);
96 * Call parent deconstructor.
98 function _Cache_OutputCompression()
101 } // end deconstructor
104 function generateID($variable)
106 $this->compression = $this->getEncoding();
107 return md5(serialize($variable) . serialize($this->compression));
111 function get($id, $group = 'default')
115 if (!$this->caching) {
119 if ($this->isCached($id, $group) && !$this->isExpired($id, $group)) {
120 $this->content = $this->load($id, $group);
122 return $this->content;
127 * Stops the output buffering, saves it to the cache and returns the _compressed_ content.
129 * If you need the uncompressed content for further procession before
130 * it's saved in the cache use endGet(). endGet() does _not compress_.
132 function end($expire = 0, $userdata = '')
134 $content = ob_get_contents();
137 // store in the cache
138 if ($this->caching) {
139 $this->extSave($this->output_id, $content, $userdata, $expire, $this->output_group);
140 return $this->content;
147 function endPrint($expire = 0, $userdata = '')
149 $this->printContent($this->end($expire, $userdata));
150 } // end func endPrint
154 * Saves the given data to the cache.
157 function extSave($id, $cachedata, $userdata, $expires = 0, $group = 'default')
159 if (!$this->caching) {
163 if ($this->compression) {
164 $len = strlen($cachedata);
165 $crc = crc32($cachedata);
166 $cachedata = gzcompress($cachedata, 9);
167 $this->content = substr($cachedata, 0, strlen($cachedata) - 4) . pack('V', $crc) . pack('V', $len);
169 $this->content = $cachedata;
171 return $this->container->save($id, $this->content, $expires, $group, $userdata);
172 } // end func extSave
175 * Sends the compressed data to the user.
180 function printContent($content = '')
182 $server = &$this->_importGlobalVariable("server");
184 if ($content == '') {
185 $content = &$this->container->cachedata;
188 if ($this->compression && $this->caching) {
189 $etag = '"PEAR-Cache-' . md5(substr($content, -40)) .'"';
190 header("ETag: $etag");
191 if (isset($server['HTTP_IF_NONE_MATCH']) && strstr(stripslashes($server['HTTP_IF_NONE_MATCH']), $etag)) {
193 header('HTTP/1.0 304');
196 // client acceppts some encoding - send headers & data
197 header("Content-Encoding: {$this->compression}");
198 header('Vary: Accept-Encoding');
199 print "\x1f\x8b\x08\x00\x00\x00\x00\x00";
205 } // end func printContent
209 * Returns the encoding method of the current dataset.
212 * @return string Empty string (which evaluates to false) means no compression
214 function isCompressed()
216 return $this->compression;
217 } // end func isCompressed
220 * Sets the encoding to be used.
222 * @param string "auto" means autodetect for every client
226 function setEncoding($encoding = 'auto')
228 $this->encoding = $encoding;
229 } // end func setEncoding
233 * Returns the encoding to be used for the data transmission to the client.
237 function getEncoding()
239 $server = &$this->_importGlobalVariable("server");
241 // encoding set by user
242 if ('auto' != $this->encoding) {
243 return $this->encoding;
245 // check what the client accepts
246 if (false !== strpos($server['HTTP_ACCEPT_ENCODING'], 'x-gzip')) {
249 if (false !== strpos($server['HTTP_ACCEPT_ENCODING'], 'gzip')) {
255 } // end func getEncoding
257 // {{{ _importGlobalVariable()
260 * Import variables from special namespaces.
263 * @param string Type of variable (server, session, post)
266 function &_importGlobalVariable($variable)
271 switch (strtolower($variable)) {
274 if (isset($_SERVER)) {
277 $var = &$GLOBALS['HTTP_SERVER_VARS'];
282 if (isset($_SESSION)) {
285 $var = &$GLOBALS['HTTP_SESSION_VARS'];
293 $var = &$GLOBALS['HTTP_POST_VARS'];
306 } // end class OutputCompression