Created
October 1, 2012 16:41
-
-
Save runion/3812913 to your computer and use it in GitHub Desktop.
class.caching.php - simple class for caching PHP files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class caching { | |
public $useCache = true; | |
public $hours_cache_remains_valid = 8; | |
private $curDirectory; | |
private $cacheFolder; // DOCUMENT_ROOT + this + $cacheFileName == cached_filename | |
private $serverFilename; | |
public $cacheFileName; // this is just the filename -- used to test if over 255 characters | |
public $cached_filename; // this includes the full path | |
public $saveCache; // boolean | |
private $ignore_directories = array( | |
"/administrator" | |
, "/translate" | |
, "/test" | |
, "/errors" | |
); | |
public function __construct() { | |
$this->serverFilename = $_SERVER['SCRIPT_FILENAME']; | |
if(!empty($this->serverFilename)) { | |
$this->curDirectory = dirname($this->serverFilename); | |
$this->cacheFolder = "/.cache".$this->curDirectory; | |
} | |
} | |
public function doCache() { | |
if( | |
$this->is_cpc_user() | |
|| sizeof(array_filter($this->ignore_directories, array($this, "ignore_directories_filter"))) | |
|| sizeof($_POST) > 0 | |
|| isset($_GET['bustcache']) | |
) { | |
$this->useCache = false; | |
} else { | |
if($this->valid_cache($this->get_cached_filename())) { | |
$this->saveCache = false; | |
} else { | |
$this->saveCache = true; | |
} | |
} | |
} | |
private function ignore_directories_filter($ignore_directory) { | |
# This function is used by array_filter directly above -- the $ignore_directory variable is one element | |
# passed by array_filter from the $this->ignore_directories array. | |
# We want to match on a substring so /test/subfolder will match and $this->useCache will be set to false, | |
# just the same as if we were in /test -- otherwise we could just do in_array | |
return strpos($this->curDirectory, $_SERVER['DOCUMENT_ROOT'].$ignore_directory) !== false; | |
} | |
public function valid_cache($cacheFile) { | |
if(!file_exists($cacheFile)) { return false; } | |
if(strlen($this->cacheFileName) > 250) { return false; } | |
$hours_cache_remains_valid = 8; | |
$max_cache_age = 60 * 60 * $hours_cache_remains_valid; | |
$cache_mtime = filemtime($cacheFile); | |
#echo $cacheFile."<br>"; | |
#echo $scriptFile."<br>"; | |
$script_mtime = filemtime($this->serverFilename); | |
# cache is valid if the file is less than $hours_cache_remains_valid old, and if the cache script was modified more recently than the generating script. | |
if($this->is_cache_expired($cache_mtime) || $this->is_cached_file_older_than_script($cache_mtime, $script_mtime)) { | |
unlink($cacheFile); | |
return false; | |
} | |
return true; | |
} | |
public function is_cache_expired($cache_mtime) { | |
$max_cache_age = 60 * 60 * $this->hours_cache_remains_valid; | |
return (time() - $max_cache_age > $cache_mtime); | |
} | |
public function is_cached_file_older_than_script($cache_mtime, $script_mtime) { | |
return ($cache_mtime < $script_mtime); | |
} | |
private function is_cpc_user() { | |
/* Determine if customer is a CPC customer. We show different contact info for paid search customers for tracking purposes. We could split off separate caches for this but it's easier to just generate the page... */ | |
if (isset($_COOKIE["__utmz"])) { | |
$AnalyticsCookie = array(); | |
foreach((array)preg_split('~([.|])(?=ut)~', $_COOKIE["__utmz"]) as $pair) { | |
if(strpos($pair, "=")) { | |
list($key, $value) = explode('=', $pair); | |
$AnalyticsCookie[$key] = $value; | |
} | |
} | |
if(isset($AnalyticsCookie['utmgclid']) && strlen($AnalyticsCookie['utmgclid']) > 0) { | |
return true; | |
} | |
} | |
if( | |
isset($_GET['gclid']) | |
|| isset($_GET['utm_nooverride']) | |
|| isset($_GET['utm_source']) | |
|| isset($_GET['utm_campaign']) | |
|| isset($_GET['utm_medium']) | |
) { | |
return true; | |
} | |
return false; | |
} | |
public function get_cached_filename() { | |
if(isset($this->cached_filename)) { return $this->cached_filename; } | |
GLOBAL $language; # we support multiple languages, a whole story in itself. | |
$this->create_cache_folder(); # make sure the folder exists first | |
$script_filename = $_SERVER['SCRIPT_FILENAME']; | |
$script_parts = explode("/", $script_filename); | |
$script = array_pop($script_parts); | |
$qs = ""; | |
ksort($_GET); # alphabetize get by keys | |
if(sizeof($_GET) > 0) { $qs = "?"; } | |
$qsArr = array(); | |
foreach($_GET as $key=>$value) { | |
array_push($qsArr, $key."=".$value); | |
} | |
$qsString = implode("+", $qsArr); # ampersands are a no-go but apparently equals signs in file names are fine | |
$qs .= $qsString; | |
$cacheFileNameTemp = str_replace(array("/", ",", "\\"), "", $script . "-" . $language . "-" . $hostTemp . "-" . $qs); # chomp / and , | |
$this->cacheFileName = str_replace(" ", "%20", $cacheFileNameTemp); # spaces to %20 -- as it should be | |
$cacheFileNameWithPath = $this->cacheFolder . "/" . $this->cacheFileName; | |
$this->cached_filename = $_SERVER['DOCUMENT_ROOT'].$cacheFileNameWithPath; | |
return $this->cached_filename; | |
} | |
private function create_cache_folder() { | |
if(!file_exists($_SERVER['DOCUMENT_ROOT'].$this->cacheFolder)) { | |
#echo "creating: ".$_SERVER['DOCUMENT_ROOT'].$this->cacheFolder."<br>"; | |
mkdir($_SERVER['DOCUMENT_ROOT'].$this->cacheFolder, 0777, true); | |
} | |
} | |
} | |
?> |
darn it.
echo PHP_EOL . $html_comment_start . " cached on ".date('jS F Y H:i', filemtime($c->get_cached_filename())) . $html_comment_end;
Could you please explain how to set this up without the prepended option for a single PHP script?
On Line 53 I think you mean to say $this->hours_cache_remains_valid
so that the property of the object is used for anyone who modifies that expecting it to change the caching time. Also you could then remove Line 52!
@yazeed I think you would want to do a 'topcache' and 'bottomcache' page include method described like in this article
And then within the top and bottom you'd do what @runion is doing in his first two comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Third time's the charm: