Кэширование данных на PHP
Кэширование является мощным инструментом в борьбе с улучшением производительности веб-приложения. Без технологии кэширования, веб-серверу приходилось бы снова и снова генерировать новый ответ для клиента тем самым теряя в производительности приложения. Если у вас динамичный проект который требует использование базы данных и выполнение при каждом запросе огромного кода, то технологии кэширования помогут вам выиграть во времени выполнения кода. Если же ваш сайт написан на чистом HTML+CSS то использовать кэширование нету смысла.
В данном примере мы посмотрим как работает мой небольшой класс по кэшированию данных в файловой системе. Сохранять данные мы будем в обычных текстовых файлах. Класс не требует долгой и нужной установки, достаточно создать для него папку-хранилище для сохранения кэша и дать ей права 777.
Установка
Можно создать папку storage рядом с PHP-файлом класса или указать свой путь к хранилищу вовремя инициализации класса.
Не забудьте дать папке права 777.
Примеры
Попробуем сохранить некоторые данные в кэш на 5 минут.
Хочу заметить, что метод $Citrus->view() может сам сохранять новые данные если они потеряли актуальность или более недоступны. Таким образом можно более не пользоваться проверкой $Citrus->has():
Если кэш с ключем from_view существует и он актуален то выводится его содержимое. Если такого файла не существует или потерял свою актуальность новые данные будут записаны в соответствии со вторым и третьим параметром.
Удаление кэша
Ну, если уже создали то нужно как-то их удалять. Для удаления файлов кэша, мы воспользуемся методом $Citrus->forget() и передадим ему ключ кэша.
Третий параметр методом $Citrus->save() и $Citrus->view() является время жизни кэша в минутах!
В данном примере мы посмотрим как работает мой небольшой класс по кэшированию данных в файловой системе. Сохранять данные мы будем в обычных текстовых файлах. Класс не требует долгой и нужной установки, достаточно создать для него папку-хранилище для сохранения кэша и дать ей права 777.
<?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
Читаем из кэша
Я был сохранен 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() является время жизни кэша в минутах!
Скачать:
13.02.2015, 22:43 -
Категория: Статьи » Программирование » PHP