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 // +----------------------------------------------------------------------+
18 require_once 'Cache.php';
21 * Graphics disk cache.
23 * The usual way to create images is to pass some arguments that describe the image
24 * to a script that dynamically creates an image. For every image of a page
25 * a new PHP interpreter gets started. This is a good way to kill your webserver.
27 * When dealing with dynamically generated images you should not call another script
28 * to generate the images but generate the images by the script that produces the page
29 * that contains the images. This is a major improvement but it's only half the way.
31 * There's no need to rerender an image on every request. A simple disk cache can reduce
32 * the computation time dramatically. This is what the class graphics_cache is for.
36 * // create an instance of the graphics cache
37 * $cache = new graphics_cache;
39 * $img = ImageCreate(...);
41 * // compute an ID for your image based on typical parameters
42 * $id = m5d( $size, $colors, $label);
44 * // check if it's cached
45 * if (!($link = $cache->getImageLink($id, 'gif'))) {
47 * // hmmm, it's not cached, create it
49 * // cacheImageLink() and cacheImage() make the ImageGIF() call!
50 * // cacheImage() returns the value of ImageGIF() [etc.], cacheImageLink() returns a URL
51 * $link = $cache->cacheImageLink($id, $img, 'gif');
55 * // Ok, let's build the ImageLink
56 * $size = getImageSize($link[0]);
57 * printf('<img src="%s" %s>', $link[1], $size[3]);
59 * // for cacheImage():
60 * // header('Content-type: image/gif'); print $cache->cacheImage($id, $img, 'gif');
63 * The class requires PHP 4.0.2+ [ImageType()]. Note that cacheImage() works with
64 * the output buffer. Modify it if required!
66 * @author Ulf Wendel <ulf.wendel@phpdoc.de>
70 class Cache_Graphics extends Cache {
76 * Make sure that the cache URL prefix points to the $cache_dir, otherwise
77 * your links will be broken. Use setCacheURL to specify the cache_url and
78 * setCacheDir() for the cache_dir.
81 * @see setCacheURL(), setCacheDir()
86 * Directory where cached files get stored.
88 * Make sure that the cache_dir is writable and offers enough space. Check
89 * also if your cache_url points to the directory. Use setCacheDir() to set
93 * @see setCacheDir(), setCacheURL()
98 * Nameprefix of cached files.
100 * Per default the prefix "graphics_" gets used. You might use this
101 * for versioning or to ease (manual) clean ups.
105 var $cache_file_prefix = 'graphics_';
109 * Cache container group.
113 var $cache_group = 'graphics';
117 * Mapping from supported image type to a ImageType() constant.
119 * Referr to the PHP manual for more informations on ImageType()
122 * @link http://www.php.net/ImageType
124 var $imagetypes = array(
133 * Instantiates a cache file container.
136 function Cache_Graphics() {
138 $this->Cache('file', array('cache_dir' => $this->cache_dir, 'filename_prefix' => $this->cache_file_prefix));
144 * Returns the content of a cached image file.
146 * This function can be used to send the image directly to the browser.
147 * Make sure that you send a correspondending header before sending the image itself.
149 * Always try to get the image from the cache before you compute it. See
150 * the class docs for an example.
152 * @param string Image-ID
153 * @param string Image type: gif, jpg, png, wbmp
154 * @return string Image file contents if a cached file exists otherwise an empty string
157 function getImage($id, $format = 'png') {
158 $id = $this->generateID($id, $format);
160 return $this->get($id, $this->cache_group);
161 } // end func getImage
165 * Returns an array with a link to the cached image and the image file path.
167 * Always try to get the image from the cache before you compute it. See
168 * the class docs for an example.
170 * @param string Image-ID
171 * @param string Image type: gif, jpg, png, wbmp
172 * @return array [ full path to the image file, image url ]
174 * @see cacheImageLink()
176 function getImageLink($id, $format = 'png') {
177 $id = $this->generateID($id, $format);
178 if (!$this->container->idExists($id, $this->cache_group))
181 $file = $this->cache_url . $this->cache_file_prefix . $id;
183 return array($this->container->getFilename($id, $this->cache_group), $file);
184 } // end func getImageLink
188 * Create an image from the given image handler, cache it and return the file content.
190 * Always try to retrive the image from the cache before you compute it.
192 * Warning: this function uses the output buffer. If you expect collisions
195 * @param string Image-ID. Used as a part of the cache filename.
196 * Use md5() to generate a "unique" ID for your image
197 * based on characteristic values such as the color, size etc.
198 * @param string Image handler to create the image from.
199 * @param string Image type: gif, jpg, png, wbmp. Also used as filename suffix.
200 * If an unsupported type is requested the functions tries to
201 * fallback to a supported type before throwing an exeption.
202 * @return string Image content returned by ImageGIF/...
203 * @throws Cache_Error
207 function cacheImage($id, $img, $format = 'png') {
209 return new Cache_Error('You must provide an ID for and image to be cached!', __FILE__, __LINE__);
211 $id = $this->generateID($id, $format);
212 $types = ImageTypes();
214 // Check if the requested image type is supported by the GD lib.
215 // If not, try a callback to the first available image type.
216 if (!isset($this->imagetypes[$format]) || !($types & $this->imagetypes[$format])) {
217 foreach ($this->imagetypes as $supported => $bitmask) {
218 if ($types & $bitmask) {
219 new Cache_Error("The build in GD lib does not support the image type $format. Fallback to $supported.", __FILE__, __LINE__);
221 return new Cache_Error("Hmm, is your PHP build with GD support? Can't find any supported types.", __FILE__, __LINE__);
226 if ($image = $this->get($id, $this->cache_group))
229 // save the image to the output buffer, write it to disk and
234 if (strtoupper($format) == "JPG") {
237 $genFormat = strtoupper($format);
240 // generate the image
241 $func = 'Image' . $genFormat;
246 $image = ob_get_contents();
249 // save the generated image to disk
250 $this->save($id, $image, 0, $this->cache_group);
253 } // end func cacheImage
257 * Create an image from the given image handler, cache it and return a url and the file path of the image.
259 * Always try to retrive the image from the cache before you compute it.
261 * @param string Image-ID. Used as a part of the cache filename.
262 * Use md5() to generate a "unique" ID for your image
263 * based on characteristic values such as the color, size etc.
264 * @param string Image handler to create the image from.
265 * @param string Image type: gif, jpg, png, wbmp. Also used as filename suffix.
266 * If an unsupported type is requested the functions tries to
267 * fallback to a supported type before throwing an exeption.
268 * @return array [ full path to the image file, image url ]
269 * @throws Cache_Error
272 function cacheImageLink($id, &$img, $format = 'png') {
274 return new Cache_Error ('You must provide an ID for and image to be cached!', __FILE__, __LINE__);
276 $id = $this->generateID($id, $format);
277 $types = ImageTypes();
279 // Check if the requested image type is supported by the GD lib.
280 // If not, try a callback to the first available image type.
281 if (!isset($this->imagetypes[$format]) || !($types & $this->imagetypes[$format])) {
282 foreach ($this->imagetypes as $supported => $bitmask)
283 if ($types & $bitmask)
284 new Cache_Error("The build in GD lib does not support the image type $format. Fallback to $supported.", __FILE__, __LINE__);
286 return new Cache_Error("Hmm, is your PHP build with GD support? Can't find any supported types.", __FILE__, __LINE__);
289 $url = $this->cache_url . $this->cache_file_prefix . $id;
290 $ffile = $this->container->getFilename($id, $this->cache_group);
292 if ($this->isCached($id, $this->cache_group) && !isExpired($id, $this->cache_group))
293 return array($ffile, $url);
295 if (strtoupper($format) == "JPG") {
298 $genFormat = strtoupper($format);
301 $func = 'Image' . $genFormat;
306 return array($ffile, $url);
307 } // end func cacheImageLink
311 * Sets the URL prefix used when rendering HTML Tags.
313 * Make sure that the URL matches the cache directory,
314 * otherwise you'll get broken links.
320 function setCacheURL($cache_url) {
321 if ($cache_url && '/' != substr($cache_url, 1))
324 $this->cache_url = $cache_url;
326 } // end func setCacheURL
329 * Sets the directory where to cache generated Images
335 function setCacheDir($cache_dir) {
336 if ($cache_dir && '/' != substr($cache_dir, 1))
339 $this->cache_dir = $cache_dir;
340 $this->container->cache_dir = $cache_dir;
341 } // end func setCacheDir
343 function generateID($variable, $format = 'png') {
344 return md5(serialize($variable)) . '.' . $format;
345 } // end func generateID
347 } // end class Cache_Graphics