
Кэширование это достаточно широкая тема, и реализация его на PHP уже описана во множестве статей. Здесь же я хочу предложить свое элементарное решение, которое имеет минимальный набор конфигурации и выполняемых операций.
Для решения этой задачи я создал класс SimpleCache
:
/** * Простой класс для кэширования контента */ class SimpleCache { /** * Путь к папке, в которую будут складываться файлы кэша */ public $cache_folder; /** * Время кэширования в секундах * Чтобы отключить кэширование нужно выставить в 0 */ public $cache_expiry = 10; /** * В этом массиве можно задать специфическое время кэширования для некоторых идентификаторов */ public $specific_cache_expiry = array( "specific_url" => 5 ); public function __construct() { $this->cache_folder = $_SERVER["DOCUMENT_ROOT"].'/dev/cache/'; } /** * Создает путь к файлу * @param string $stringIdentifier – идентификатор контента (например URL) */ private function createFilePath($stringIdentifier) { return $this->cache_folder . md5($stringIdentifier) . ".txt"; } /** * Читает строку из кэша * @param string $stringIdentifier – идентификатор контента (например URL) * @param int expiry – максимальный «возраст» файла в секундах * @return mixed содержимое кэша или false */ public function Read($stringIdentifier) { if ($this->cache_expiry specific_cache_expiry[$stringIdentifier]) ? $this->specific_cache_expiry[$stringIdentifier] : $this->cache_expiry; $filePath = $this->createFilePath($stringIdentifier); if (file_exists($filePath) && (time() - filemtime($filePath)) < $expiry) { return file_get_contents($filePath); } return FALSE; } /** * Записывает строку в кэш * @param string $stringIdentifier – идентификатор контента (например URL) * @param string $content – кэшируемый контент */ public function Write($stringIdentifier, $content) { if ($this->cache_expiry createFilePath($stringIdentifier); file_put_contents($filePath, $content); } }
В нем предусмотрены следующие настройки в виде публичных полей:
$cache_folder
— путь к папке, в которую будут складываться файлы кэша$cache_expiry
— глобальное время кэширования$specific_cache_expiry
— позволяет задать специфическое время кэширования для отдельных идентификаторов в виде массива формата идентификатор=>время кэширования
Важной особенностью этого класса, что методы для чтения и записи принимают некий строковой идентификатор контента. В общем случае это URL кешируемой страницы, но в идеале может быть все что угодно.
Имя кэш-файла формируем из пути к папке кэша и сгенерированного md5 хеша идентификатора.
Использование класса сводится к вызову методов Read()
и Write()
:
// Первый тест $cache = new SimpleCache(); $identifier1 = "simple_url"; if (!$content1 = $cache->Read($identifier1)) { $content1 = $identifier1 . " was cached at ".date('H:i:s'); $cache->Write($identifier1, $content1); } echo $content1; echo "<br/>"; // Второй тест $identifier2 = "specific_url"; if (!$content2 = $cache->Read($identifier2)) { $content2 = $identifier2 . " was cached at ".date('H:i:s'); $cache->Write($identifier2, $content2); } echo $content2;
Если при попытке чтения из кэша получаем FALSE, то нужно сформировать контент и записать его в кэш, что бы следующий раз он уже прочитался оттуда.
При первом запуске приведенного скрипта, получаем такой результат:
simple_url was cached at 16:45:20 specific_url was cached at 16:45:20
Этот же результат выводится каждый раз при обновлении страницы, а через пять секунд вторая строка обновляется:
simple_url was cached at 16:45:20 specific_url was cached at 16:45:25
Через 10 секунд обновляются они обе:
simple_url was cached at 16:45:30 specific_url was cached at 16:45:30
Думаю при просмотре кода будет понятно почему мы получили именно такой результат — глобальное время кэширования выставлено в 10 секунд, но для второго идентификатора задано свое, особое время — 5 секунд.
В своем решении я придерживался принципа простоты и минимализма.
Если вам нужно иметь более изощренную логику кеширования, то можно расширить этот класс, или же поискать более продвинутые готовые решения.