Кэширование данных в PHP с помощью CitrusLib
Кэширование является мощным инструментом в борьбе с улучшением производительности веб-приложения. Без технологии кэширования, веб-серверу приходилось бы снова и снова генерировать новый ответ для клиента тем самым теряя в производительности приложения. Если у вас динамичный проект который требует использование базы данных и выполнение при каждом запросе огромного кода, то технологии кэширования помогут вам выиграть во времени выполнения кода. Если же ваш сайт написан на чистом HTML+CSS то использовать кэширование нету смысла.
В данном примере мы посмотрим как работает мой небольшой класс по кэшированию данных в файловой системе. Сохранять данные мы будем в обычных текстовых файлах. Класс не требует долгой и нужной установки, достаточно создать для него папку-хранилище для сохранения кэша и дать ей права 777.
>> Скачать библиотеку с примерами (Citruslib-phpCache.zip)
Данную библиотеку назвал Citrus. Посмотри ее исходный код:
<?php define('DS', DIRECTORY_SEPARATOR); class Citrus { public $storage = ''; public function __construct($storage='') { if(!$storage) { // Путь не задан, указываем его по умолчанию $this->storage = __DIR__. DS . 'storage' . DS; } else { // Задан собсвенный путь к хранилищу $this->storage = $storage; } if(!is_writable($this->storage)) { die('Cache folder ('.$this->storage.') need to be 777 permissions'); } } public function __destruct() { /* * Чистильщик старых кэш-файлов */ $cached_files = glob($this->storage . '*'); if(count($cached_files)) { foreach($cached_files as $filename) { if(!$this->is_actual($filename)) { $this->delete($filename); } } } } public function save($cache_key, $source, $minutes=0) { /* * Сохранение кэш-файла */ $cache_filename = md5($cache_key); $Open = fopen($this->storage . $cache_filename, 'w'); $final_source = "TIME=". ($minutes * 60) ."\n". $source; fwrite($Open, $final_source); return $source; } public function has($cache_key) { /* * Проверка на существование и актуальность кэш-файла */ $cache_filename = $this->storage . md5($cache_key); if(!file_exists($cache_filename)) { return False; } else { return $this->is_actual($cache_filename); } } public function view($cache_key, $source='', $time=0) { /* * Просмотр содержимоего кэш-файла с возможность пересохранить */ $cache_filename = $this->storage . md5($cache_key); if($this->has($cache_key)) { $Source = file_get_contents($cache_filename); return preg_replace("#TIME=\d+\n#", '', $Source); } else { if(!$source) { return $source; } else { return $this->save($cache_key, $source, $time); } } } public function forget($cache_key) { /* * Удаление кэш-файла по его ключу */ $cache_filename = $this->storage . md5($cache_key); return $this->delete($cache_filename); } private function delete($filename) { /* * Удаление кэш-файла через его путь */ if(file_exists($filename)) { return unlink($filename); } else { return True; } } public function is_actual($filename) { /* * Проверка на актуальность кэш-файла */ $Source = file_get_contents($filename); preg_match("#TIME=(\d+)#", $Source, $matches); if( (filemtime($filename) + $matches[1]) < time() ) { $this->delete($filename); return False; } else { return True; } } } ?>
Установка
Можно создать папку storage рядом с PHP-файлом класса или указать свой путь к хранилищу вовремя инициализации класса. Не забудьте дать папке права 777.
Примеры
Попробуем сохранить некоторые данные в кэш на 5 минут.
<?php header('Content-Type: text/html; charset=utf-8'); include_once('Citrus.php'); /* * Указать новый путь для сохранения кэша можно таким образом: * $Citrus = new Citrus('/var/www/store/'); // <- Linux * $Citrus = new Citrus('D:\\AppServ\www\storage\'); // <- Windows */ $Citrus = new Citrus; if(!$Citrus->has('time')) { echo "Сохраняем данные в кэш.<br>"; echo $Citrus->save('time', 'Я был сохранен ' . date('Y-m-d H:i:s') , 5); } else { echo 'Читаем из кэша<br>'; echo $Citrus->view('time'); echo '<br>Сейчас: '.date('Y-m-d H:i:s').'<br>'; } ?>
Результат работы:
Читаем из кэша Я был сохранен 2013-03-11 20:46:49 Сейчас: 2013-03-11 20:50:14
Хочу заметить, что метод $Citrus->view() может сам сохранять новые данные если они потеряли актуальность или более недоступны. Таким образом можно более не пользоваться проверкой $Citrus->has():
<?php echo $Citrus->view('from_view', 'Я сразу из обзорщика', 10); ?>Если кэш с ключем from_view существует и он актуален то выводится его содержимое. Если такого файла не существует или потерял свою актуальность новые данные будут записаны в соответствии со вторым и третьим параметром.
Удаление кэша
Ну, если уже создали то нужно как-то их удалять. Для удаления файлов кэша, мы воспользуемся методом $Citrus->forget() и передадим ему ключ кэша.<?php $Citrus->forget('my_key'); ?>Третий параметр методом $Citrus->save() и $Citrus->view() является время жизни кэша в минутах!
Если есть какие либо замечания по данной статье прошу напишите в комментариях.
- Какие методики кэширования используете вы?
- Какие функции вы хотели бы увидеть в CitrusLib в будущем?
// Путь не задан, указываем его по умолчанию
$this->storage = (rtrim($_SERVER['DOCUMENT_ROOT'], DS) . DS . "cache" . DS);
так проше и удобней