<?php
/***********************************
gimmecache.php
@ 2002 Sam Yapp www.samscripts.com
You are free to use modify and do whatever you like with this script.
Usage:
*** To cache a whole page, ***
near the top of your script,
include_once("gimmecache.php");
$cache = new gimmecache("path/to/store/cached/files/in", 60); // refresh cache after 60 seconds
$cache->cache("a_unique_name_identifying_this_cache");
*** To cache part of a script, ie. big database query ***
include_once("gimmecache.php");
$cache = new gimmecache("path/to/store/cached/files/in", date("Y-m-d 00:00:00")); // refresh cache once a day
if( $cache->cache("a_unique_name_identifying_this_cache")){ // cache() returns true if the code needs to be refreshed
// all the code you want to cache goes here, eg.
$result = mysql_query($really_big_and_slow_query);
while( list( $f1, $f2, $f3, $f4) = mysql_fetch_row($result)){
echo "Field1 $f1, Field2 $f2, Field3 $f3, Field4 $f4<br>\n";
}
$cache->stop(); // finish caching this bit of code
}
// The sql query and output of the data will only occur the first time each day that the script is requested.
// the output is stored in the cache and is output to the browser as html which for a big query will be faster.
*** To remove a cached file - sometimes you may need to refresh a script the next time it is called, but not this time ***
$cache->expirecache($cache_identifier);
*** to replace one or more strings in the cached output before outputting it to the web browser
$cache->cache($cachepath, $expirytime, $search = array("firstvalue", "secondvalue"), array("firstreplacement", "secondreplacement"));
// error checking: the variable $_THE_CACHE_ERRORS is an array containing text descriptions of any errors. It will be empty if no errors occur
************************************/
// you can change these:
$_DEFAULT_CACHE_PATH = "./cached"; // path to store cached files in - must be php writable
$_USE_DATABASE = ""; // enter the database table name here to use db instead of files - see below
/*******************************
if you want to cache to a mysql database, enter the name of the table
in $_USE_DATABASE above.
the database should have the following structure:
CREATE TABLE cached (
id varchar(32) NOT NULL default '',
updated datetime NOT NULL default '0000-00-00 00:00:00',
file text NOT NULL,
PRIMARY KEY (id)
)
at present, this class simply calls mysql_query($sql) - ie it assumes that you
have already opened a database connection with mysql_connect and mysql_select_db
elsewhere in the script.
if $_USE_DATABASE = "" then files will be used for caching. (quicker, in most cases ? )
******************************/
// do NOT change the names of these - unless you change them throughout the script
$_THE_CACHE_FILENAME = array(); // global variable holds filenames of cached files
$_THE_CACHE_ERRORS = array(); // store any error messages generated
$_THE_CACHE_EXISTS = array();
$_THE_CACHE_REPLACE = array();
class gimmecache{
var $cachepath;
var $expireafter;
var $expiretype;
var $filename;
var $connection;
var $usedb;
function setexpiry($expireafter = 60){ // sets either the number of seconds before re-caching or a date-string after which to expire the cache
$this->expireafter = $expireafter;
if( is_int($expireafter) ){
$this->expiretype = "sec";
}else{
$this->expiretype = "date";
}
}
function gimmecache( $cachepath = "", $expireafter = 60, $connection = 0){ // cachepath is where cached files will be stored
global $_DEFAULT_CACHE_PATH;
global $_USE_DATABASE;
if( $_USE_DATABASE != "" ){
$this->usedb = $_USE_DATABASE;
$this->connection = $connection;
}else{
$this->usedb = false;
}
$this->cachepath = ($cachepath == "" ? $_DEFAULT_CACHE_PATH : $cachepath);
$this->setexpiry($expireafter);
$this->filename = "";
}
function expirecache($cachename){
$filename = $this->cachepath."/".md5($cachename).".cache";
@unlink($filename);
}
function cache($cachename, $expireafter = "", $search = array(), $replace=array()){
$this->cachename = $cachename;
if( $expireafter == "" ) $expireafter = $this->expireafter;
$this->setexpiry($expireafter);
$update = 0;
if( $this->usedb ){
$filename = md5($cachename);
$res = @mysql_query("SELECT updated, file FROM ".$this->usedb." WHERE id='".$filename."'")or die(mysql_error());
if( mysql_num_rows($res) == 0 ){
$update = 1;
$exist = 0;
}else{
list( $updated, $f) = mysql_fetch_row($res);
$updated = strtotime($updated);
$exist = 1;
}
}else{
$filename = $this->cachepath."/".md5($cachename).".cache";
if( !file_exists($filename) ){
$update = 1;
$exist = 0;
}else{
$exist = 1;
$updated = filemtime($filename);
}
}
if( $exist ==0 || $updated < ($this->expiretype == "sec" ? time() - $this->expireafter : strtotime($this->expireafter))){
$update = 1;
}
if( $update){
ob_start( "_the_cache_capture");
global $_THE_CACHE_FILENAME;
global $_THE_CACHE_EXISTS;
global $_THE_CACHE_REPLACE;
$_THE_CACHE_FILENAME[] = $filename;
$_THE_CACHE_EXISTS[] = $exist;
$countcache = count( $_THE_CACHE_REPLACE);
$_THE_CACHE_REPLACE[$countcache]["search"] = $search;
$_THE_CACHE_REPLACE[$countcache]["replace"] = $replace;
return true;
}else{
global $_THE_CACHED_ERRORS;
if( $this->usedb ){
echo str_replace($search, $replace, $f);
}else{
if( count($search) == 0 ){
if( !@readfile( $filename)) $_THE_CACHE_ERRORS = "readfile failed for ".$this->filename;
}else{
$f = join("", file($filename));
echo str_replace($search, $replace, $f);
}
}
return false;
}
}
function stop($returnbuffer = false){ // if returnbuffer is true, returns the contents of the cache to the calling script
if( $returnbuffer ){
$ret = ob_get_contents();
}else{
$ret = "";
}
ob_end_flush();
return $ret;
}
}
function _the_cache_capture(&$output){
global $_THE_CACHE_FILENAME;
global $_THE_CACHE_ERRORS;
global $_THE_CACHE_EXISTS;
global $_THE_CACHE_REPLACE;
global $_USE_DATABASE;
$numcaches = count($_THE_CACHE_FILENAME);
if( $numcaches != 0 ){
$filename = $_THE_CACHE_FILENAME[$numcaches-1];
if( $_USE_DATABASE != "" ){
if( $_THE_CACHE_EXISTS[$numcaches-1] == 1 ){
$sql = "UPDATE cached SET updated=now(), file='".addslashes($output)."' WHERE id='".$filename."'";
}else{
$sql = "INSERT INTO cached (id, updated, file) VALUES ('".$filename."', now(), '".addslashes($output)."')";
}
@mysql_query($sql);
}else{
$fo = @fopen($filename, "w");
if( $fo ){
if( !@fwrite( $fo, $output)) $_THE_CACHE_ERRORS[] = "Error writing to file $filename.";
@fclose( fo);
}else{
$_THE_CACHE_ERRORS[] = "Failed opening file $filename for output.";
}
}
array_pop($_THE_CACHE_FILENAME);
}else{
$_THE_CACHE_ERRORS[] = "No active caches.";
}
if( count( $_THE_CACHE_REPLACE[$numcaches-1]["search"]) != 0 ){
$result = str_replace($_THE_CACHE_REPLACE[$numcaches-1]["search"], $_THE_CACHE_REPLACE[$numcaches-1]["replace"], &$output);
}else{
$result = &$output;
}
return $result;
}
?>
|