Version: 1.0

Type: Function

Category: Graphics

License: GNU General Public License

Description: A simple function for caching images generated by php/gd. http://www.kern-online.dk/phps/imcache.phps



<?php
/**
  * imcache (a function for caching images generated by php/gd)
  * 
  * Copyright (C) 2003 Kern Herskind Hansen
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  *
  * Requirements:
  *
  * It requires GD library.
  *
  *
  * Usage:
  *
  * To enable imcache in your image generating scripts, you have to do three
  * things:
  * 1) Include imcache.php (this file) in your script.
  * 2) Wrap your image generating code in a function that returns an image handle.
  *    NOTE: Don't use imagepng()/imagejpg()/imagegif() in this function (this is 
  *    handled by imcache function) and don't call imagedestroy($return_im_handle) 
  *    on the image handle you are about to return!
  * 3) Call imcache function with appropiate arguments:
  *    $cachepath - path to the directory where cached files should reside. Make
  *    sure that the webserver has write rights to the directory.
  *    $type - the type of image you want to output, must be either "gif", "jpeg"
  *    or "png".
  *    $function - string containing the function to call (see example)
  *
  * 
  * Example:
  *
  * <code>
  * <?php
  *   function blankcanvas($xdim, $ydim)
  *   {
  *     return imagecreate($xdim, $ydim);
  *   }
  *   imagecache("./cachedimages", "png", "blankcanvas(10, $_GET['height'])");
  * ?>
  * </code>
  * 
  * In the above example we have a function called blankcanvas that returns a
  * handle to an image oh variable dimensions. Note how the last argument of 
  * imcache function looks; it's a string explaining how blankcanvas should 
  * be called...
  *
  *
  * @author             Kern Herskind Hansen <kern@kern-online.dk>
  * @date               2003-09-04
  * @license            LGPL (http://www.gnu.org/licenses/lgpl.html)
  * @changes            1.0 first version
  *
  */ 
function imcache($cachepath, $type, $function)
{
    // Compose a uniqe'ish filename for cacheing.
    $filename = urlencode($_SERVER["REQUEST_URI"]) . "---" . urlencode($function);
    $filepath = realpath($cachepath)."/".$filename;
    
    
    if(file_exists($filepath) and filectime($_SERVER["PATH_TRANSLATED"]) < filectime($filepath))
    {
        // if a file is there - stream response directly 
        header("Content-type: ".image_type_to_mime_type(exif_imagetype($filepath)));
        @readfile($filepath);
        touch($filepath);
    }
    else
    {
        // if a file isn't there - call function that wil generate image

        // first make sure that $function "looks" like a function call
        if(ereg("^\s*[_a-z0-9-]+\s*\(.*\)\s*;?\s*$", $function))
        {
            $im = FALSE;

            // adjust function exspression ... (it needs to start with "$im = " and end with ";")
            if(!(ereg(";\s*$", $function)))
                $function = $function.";";
            $function = '$im = '.$function;

            // black magic ;-)
            eval($function);
            
            header ("Content-type: image/$type");
            switch($type)
            {
                case "gif":
                    imagegif($im);
                    imagegif($im, $filepath);
                    break;
        
                case "jpeg":
                    imagejpeg($im);
                    imagejpeg($im, $filepath);
                    break;
                    
                case "png":
                    imagepng($im);
                    imagepng($im, $filepath);
                    break;
            }
            imagedestroy($im);
        }
        else
        {
            trigger_error('imcache: $function argument not valid, must be in the form "foo(arg, arg)" on line '. __LINE__ ." in ". __FILE__);
        }

    }
}

?>