Version: 0.2
Type: Class
Category: HTML
License: GNU General Public License
Description: Persistently cache whole pages identified by their md5 hash.
<? /* * $Header: /var/cvs/formcache/formcache.php,v 1.6 2001/04/26 16:44:24 mfischer Exp $ * * Class : formcache * Version : 0.2 * Author : [email protected] * http://josefine.ben.tuwien.ac.at/~mfischer/ * * Description : Class which handles cached form submission * * Exaomple : * If someone just submitted the form and its in the cache, * serve the user the cached result : * * $fc = new formcache( 'myform', '/tmp/php/'); * * if( $fc->exists( array_merge( $HTTP_POST_VARS, $HTTP_GET_VARS))) * echo join( '', $fc->serve()); * else * doGetResult(); // that's up to you * * * Somewhere in 'doGetResult()' you then write the output to the cache : * * $fc->cache( $output); */ // That's up to the end-developer, really // error_reporting( E_ALL ^ E_NOTICE); /* Change this to a default setting which makes sense to your enviroment FORMCACHE_NAMESPACE - Is part of the name of the cachefile to easier distingiush cached files from different forms FORMCACHE_CACHDIR - The directory where everything gets writte to and served from Make sure Apache/PHP has the proper rights to write and read files from there If the directory does not exist the class tries to create it automatically */ define( 'FORMCACHE_NAMESPACE', 'formcache'); define( 'FORMCACHE_CACHEDIR', '/tmp/'); /** * Provides detection if a FORM was submitted a second time a feed * feed brwoser with resulting page from cache * @access public * @author Markus Fischer <[email protected]> * @link http://josefine.ben.tuwien.ac.at Homepage of the author * @copyright Netway AG */ class formcache { /** * Namespace declaration * @var string * @access private */ var $namespace; /** * Directory name where to store/retrieve cached files * @var string * @access private */ var $cachedir; /** * Cache filename * @var string * @access private */ var $cachefile; /** * Wheter use compression or not when writing to the cache. Defaults to false. * @var boolean * @access public */ var $compress; /** * Contains last error message * @var string * @access public */ var $err; /** * Constructor * * Instances a new formcheck object. * * @param string The Namespace the cache lives under * @param string Optional directory for reading/writing cached files. Defaults to FORMCACHE_CACHDIR * @param boolean Whether use gzip compression (TRUE) or not (FALSE) */ function formcache( $namespace = FORMCACHE_NAMESPACE, $cachedir = FORMCACHE_CACHDIR, $compress = false) { $this->namespace = $namespace; if( empty( $this->namespace)) $this->namespace = FORMCACHE_NAMESPACE; $this->cachedir = $cachedir; if( empty( $this->cachedir)) $this->cachedir = FORMCACHE_CACHEDIR; else if( $this->cachedir[ strlen( $this->cachedir) - 1] != '/') $this->cachedir .= '/'; if( ! @is_dir( $this->cachedir)) { $dirs = split( '/', $this->cachedir); $createdir = ''; foreach( $dirs as $dir) { $createdir .= '/' . $dir; @mkdir( $createdir, 0775);} } $this->cachefile = ''; if( $compress) $this->compress = true; else $this->compress = false; } /** * Elicit the disambiguatity for cache-hits by means of the form elements * * @param array Form elements * @return boolean True if uniqie identifier (cachefile) has been generated; False if not (ie. $form was empty or not an array) * @access public */ function formdata( $form) { $param = array(); if( empty( $form) || ( ! gettype( $form) == 'array')) return $this->error( 'Form elements array is empty or not of type 'array''); // Different browsers return form elements in different orders => fix this! ksort( $form, SORT_STRING); foreach( $form as $key => $value) $param[] = urlencode( $key) . '=' . urlencode( $value); $this->cachefile = $this->cachedir . $this->namespace . '-' . md5( join( '&', $param)) . '.cache'; return true; } /** * Check wether a cached file exists or not * * @param array A optional hash containing all form elements for determining the disambiguatity. * Use this if you haven't called $this-set() before * * @return boolean True if a cached file exists; False if not (or there was no cachefile previously generated) * * @acces public */ function exists( $form = '') { $this->formdata( $form); if( empty( $this->cachefile)) return $this->error( 'Cachefile is empty; initialize first with method formadata()'); if( file_exists( $this->cachefile)) return true; else return $this->error( 'Cachefile does not exist'); } /** * Serve file from cache * * @param array A optional hash containing all form elements for determining the disambiguatity. * Use this if you haven't called $this-set() before * * @return mixed Array containing the cached file, line by line. False on failure * * @access public */ function serve( $form = '') { $this->formdata( $form); if( empty( $this->cachefile)) return $this->error( 'Cachefile is empty; initialize first with method formadata()'); if( $this->exists()) return @gzfile( $this->cachefile); else return false; } /** * Caches the data * * Note that this function overwrites without warning; use exists() before inserting * * @param array Data to cache * * @return boolean True on successful cache insertion; False if something has gone wrong * * @access public */ function cache( $data, $form = '') { if( empty( $data) || ( gettype( $data) != 'array')) return $this->error( 'Data is empty or not an array'); if( ! empty( $form)) $this->formdata( $form); if( empty( $this->cachefile)) return $this->error( 'Cachefile is empty; initialize first with method formdata()'); if( ( $fp = fopen( $this->cachefile, 'wb'))) { if( $this->compress) { $compressed = gzencode( join( '', $data)); if( strlen( $compressed) != fwrite( $fp, $compressed, strlen( $compressed))) { fclose( $fp); return $this->error( 'Compressed data only partially written; low on disk space ?'); } } else foreach( $data as $line) if( strlen( $line) != fwrite( $fp, $line, strlen( $line))) { fclose( $fp); return $this->error( 'Data only partially written; low on disk space ?'); } if( fclose( $fp)) return true; else $this->error( 'Can't close file handle'); } else return $this->error( 'Can't open cache file for writing'); } /** * Stores error message * * This method is just for convinience. all it does it stores the parameter in a member variable $this->errmsg and always returns false * * @param string Optional error message string * @return boolean Always returns false * @access private */ function error( $message = '') { $this->err[] = $message; return false; } } ?>