快取對效能至關重要,許多開發者過度依賴框架而忽略基礎。本文介紹 phpGuru 開源的 Cache 類別,採用共享記憶體(/dev/shm)儲存,所有方法皆為靜態,使用簡單。
採用 phpGuru 授權,商業用途需付費,慈善/教育機構有優惠,詳見 官網。
Start()/End())。Get()/Put())。class Cache {
public static $enabled = true;
protected static $store = '/dev/shm/';
protected static $prefix = 'cache_';
protected static function write($group, $id, $ttl, $data) {
$filename = self::getFilename($group, $id);
if ($fp = @fopen($filename, 'xb')) {
if (flock($fp, LOCK_EX)) fwrite($fp, $data);
fclose($fp);
touch($filename, time() + $ttl);
}
}
protected static function read($group, $id) {
return file_get_contents(self::getFilename($group, $id));
}
protected static function isCached($group, $id) {
$filename = self::getFilename($group, $id);
if (self::$enabled && file_exists($filename) && filemtime($filename) > time()) return true;
@unlink($filename);
return false;
}
protected static function getFilename($group, $id) {
$id = md5($id);
return self::$store . self::$prefix . "{$group}_{$id}";
}
public static function setPrefix($prefix) { self::$prefix = $prefix; }
public static function setStore($store) { self::$store = $store; }
}
class OutputCache extends Cache {
private static $group, $id, $ttl;
public static function Start($group, $id, $ttl) {
if (self::isCached($group, $id)) { echo self::read($group, $id); return true; }
else { ob_start(); self::$group=$group; self::$id=$id; self::$ttl=$ttl; return false; }
}
public static function End() {
$data = ob_get_contents(); ob_end_flush();
self::write(self::$group, self::$id, self::$ttl, $data);
}
}
class DataCache extends Cache {
public static function Get($group, $id) {
if (self::isCached($group, $id)) return unserialize(self::read($group, $id));
return null;
}
public static function Put($group, $id, $ttl, $data) {
self::write($group, $id, $ttl, serialize($data));
}
}
if (!OutputCache::Start('group', 'unique_id', 600)) {
// ... 輸出內容 ...
OutputCache::End();
}
if (!$data = DataCache::Get('group', 'unique_id')) {
$data = time(); // 取得資料
DataCache::Put('group', 'unique_id', 10, $data);
}
echo $data;
$dir = !empty($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '.';
$dh = opendir($dir);
while ($filename = readdir($dh)) {
if ($filename == '.' || $filename == '..') continue;
if (filemtime($dir . DIRECTORY_SEPARATOR . $filename) < time()) {
unlink($dir . DIRECTORY_SEPARATOR . $filename);
}
}