Skip to content

Instantly share code, notes, and snippets.

@samuelantonioli
Last active February 8, 2021 14:46
Show Gist options
  • Save samuelantonioli/f1885bf42d8d7385fc5c5115d4c02eaa to your computer and use it in GitHub Desktop.
Save samuelantonioli/f1885bf42d8d7385fc5c5115d4c02eaa to your computer and use it in GitHub Desktop.
PHP Simple File Cache with Lifetime Strategy
<?php
/***
*
* CACHE
*
* create the cache_directory BEFORE you use this cache.
* it doesn't generate it automatically to avoid possible bugs.
*
***/
class CACHE {
protected static $_instance = null;
protected static $_config = null;
public static function getInstance() {
if (null === self::$_instance) {
self::$_instance = new self;
self::$_config = array(
'hash_key' => true,
'cache_directory' => './cache',
'expires' => 86400, // seconds; 1 day
);
}
return self::$_instance;
}
protected static function to_key($key) {
if (null != self::$_instance) {
if (
true === @array_key_exists('hash_key', self::$_config) &&
// truthy value
true == self::$_config['hash_key']
) {
// md5 could cause collisions, but it is pretty unlikely
// we substr the $key to prevent DoS attacks
return md5(substr($key, 0, 1024));
}
}
return $key;
}
protected function to_path($key) {
$key = self::to_key($key);
$cache_dir = self::$_config['cache_directory'];
// DIRECTORY_SEPARATOR
$path = join('/', array(rtrim($cache_dir, '/'), $key));
return $path;
}
public function config($data = null) {
if (true === @is_array($data)) {
self::$_config = array_merge(self::$_config, $data);
}
return self::$_config;
}
public function is_valid($key) {
$path = $this->to_path($key);
if (true === @is_file($path)) {
$timestamp = @filemtime($path);
if ($timestamp === false) {
return false;
}
$current = (new DateTime('now'))->getTimestamp();
$diff = $current - $timestamp;
if (
$diff <= self::$_config['expires'] ||
$diff < 0
) {
return true;
} else {
return false;
}
} else {
return false;
}
}
public function get($key) {
$path = $this->to_path($key);
return @file_get_contents($path);
}
public function get_filename($key) {
return $this->to_path($key);
}
public function set($key, $value) {
$path = $this->to_path($key);
return @file_put_contents($path, $value, LOCK_EX);
}
public function invalidate($key) {
$path = $this->to_path($key);
if (true === @is_file($path)) {
return @unlink($path);
}
return true;
}
// prevent creation and cloning
protected function __clone() {
}
protected function __construct() {
}
}
<?php
/**
* simple singleton cache
*
* - uses filesystem
* - implements lifetime strategy
*
**/
require_once('cache.php');
function normalized_request_uri($uri = null) {
if (null == $uri) {
$uri = $_SERVER['REQUEST_URI'];
}
$val = explode('?', $uri, 2);
return rtrim($val[0], '/');
}
$key = normalized_request_uri();
$cache = CACHE::getInstance();
// (optional) configurate
$config = array(
'hash_key' => true,
'cache_directory' => './cache',
'expires' => 3600, // 1 hour
);
$cache->config($config);
// show usage
if ($cache->is_valid($key)) {
// get cache file content
echo $cache->get($key) . "\n";
// get cache filename
echo $cache->get_filename($key) . "\n";
} else {
// e.g. render template
$value = '<html>...</html>';
echo $cache->set($key, $value) . "\n";
}
// if you want to invalidate a cache entry
$cache->invalidate($key);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment