УрокСистема кэширования Drupal 7. Часть вторая: программное управление кэшем.
Сегодня наконец дошли руки написать продолжение серии статей о кэшировании. В первой части были рассмотрены сегменты кэша, которые находятся в ядре седьмого Друпала. Сегодня же мы поговорим о том, как работать с кэшем программно. Для примера создадим модуль, который предоставляет свой сегмент кэша и управление им.
Шаг первый. Создание нового сегмента кэша.
Назовём наш модуль, например, Example cache. Для создания своего сегмента кэша практически всегда используется клон стандартной таблицы {cache}, поэтому и мы не будем исключением. В example_cache.install имплементируем hook_schema(), чтобы добавить свою таблицу:
/** * Implements hook_schema(). */ function example_cache_schema() { $schema['cache_example'] = drupal_get_schema_unprocessed('system', 'cache'); $schema['cache_example']['description'] = 'Cache table stores some example data.'; return $schema; }
В принципе всё. Теперь при инсталяции модуля в базе данных будет создана новая таблица с необходимыми полями.
Шаг второй. Заботимся о сбросе кэша.
Вторым шагом я обычно сразу делаю то, о чём в самом конце можно забыть - предусмотреть автоматический сброс кэша. При нажатии на кнопку "Очистка кэша" в разделе "Производительность" (/admin/config/development/performance) должны очиститься все таблицы (сегменты) с кэшем. И наш только что добавленный сегмент не должен быть исключением. Для этого в example_cache.module имплементируем hook_flush_caches(). Он возвращает названия сегментов (таблиц), которые будут очищены при общем сбросе кэша:
/** * Implements hook_flush_caches(). */ function example_cache_flush_caches() { return array('cache_example'); }
Шаг третий. Кэшируем данные.
Давайте теперь для разнообразия закэшируем какие-нибудь данные. Для наглядности я решил закэшировать бесполезную, но достаточно длительную операцию по заполнению массива миллионом элементов. Повесим эту операцию, например, на hook_init():
/** * Implements hook_init(). */ function example_cache_init() { timer_start('example_cache'); $array = array(); for ($i = 0; $i < 1000000; $i++) { $array[] = $i; } $timer = timer_read('example_cache') / 1000; drupal_set_message('Мы получили результат за ' . $timer . ' секунд'); }
Как видите, пока никакого кэша нет. У меня эта операция выполняется примерно две секунды. А теперь давайте добавим сюда кэширование:
/** * Implements hook_init(). */ function example_cache_init() { timer_start('example_cache'); // Указываем любое уникальное имя. $cache_id = 'some_unique_name'; // Пытаемся получить результат из нашего сегмента кэша. $cache = cache_get($cache_id, 'cache_example'); // Если результат был найден в кэше - то просто забираем его. if (!empty($cache->data)) { $array = $cache->data; } else { // Если же результат не был найден, то вычисляем его и сохраняем в кэше. $array = array(); for ($i = 0; $i < 1000000; $i++) { $array[] = $i; } // Сохраняем результат в кэше на 15 минут. cache_set($cache_id, $array, 'cache_example', REQUEST_TIME + 15 * 60); } $timer = timer_read('example_cache') / 1000; drupal_set_message('Мы получили результат за ' . $timer . ' секунд'); }
После добавления кэша время выполнения этой функции существенно уменьшилось.
В принципе, это единственный верный способ работы с кэшем и другого пока не придумано. Однако на практике могут применяться ещё несколько функций. Давайте рассмотрим их все.
Сохранение данных в кэше
Для добавления данных в хранилище кэша используется функция cache_set. Она имеет следующие параметры:
- $cid - уникальный Cache ID (primary key) хранимых данных.
- $data - данные в любом формате, которые надо закэшировать. Данные автоматически сериализуются.
- $bin - сегмент кэша (в нашем случае - таблица в бд), куда надо сохранить данные. Если не указать этот параметр, то данные будут храниться в {cache}.
- $expire - задаёт срок годности кэша в милисекундах (Unix timestamp). Он задаётся прибавлением необходимого времени жизни кэша к текущему времени. Кроме числового значения этот параметр может принимать значения CACHE_PERMANENT или CACHE_TEMPORARY. В первом случае данные не будут удалены из кэша, пока вы их не удалите принудительно (очисткой сегмента либо же удалением данных с указанным $cid). Во втором случае данные будут очищены при первой же общей очистке кэша с истёкшим сроком годности.
Получение кэшированных данных
Для получения данных из кэша используется функция cache_get. Её параметры:
- $cid - Cache ID - уникальный идентификатор кэша, который надо получить.
- $bin - сегмент кэша (в нашем случае - таблица в бд), откуда надо забрать результат. Если не передать этот параметр, то данные будут браться из сегмента {cache}.
Если данных в кэше нет, либо же у него истёк срок годности (когда текущее время больше времени срока годности кэша), то возвращается пустой результат.
Для получения результата так же может использоваться функция cache_get_multiple. Первый её параметр отличается от cache_get лишь тем, что она принимает набор (массив) cid'ов, данные для которых надо получить. После вызова cache_get_multiple из этого массива удаляются все cid'ы, для которых был найден результат.
Очистка (сброс) кэша
Для удаления кэшированных данных используется функция cache_clear_all. Её параметры:
- $cid - Cache ID, который надо удалить из хранилища данных. Если не указан, то будут удалены все данные с истёкшим сроком годности и c CACHE_TEMPORARY.
- $bin - название сегмента кэша, из которого надо удалить данные. Если указан указан $cid, то этот аргумент обязателен.
- $wildcard - если указан как TRUE, то все записи, у которых Cache ID начинается с $cid будут удалены. Если $cid имеет значение *, то будет очищен весь сегмент.
Несколько примеров использования:
// Очищает кэш с истёкшим сроком годности и CACHE_TEMPORARY // из {cache_block} и {cache_page}. cache_clear_all(); // Полностью очищает сегмент {cache_example}. cache_clear_all('*', 'cache_example', TRUE); // Удаляет из сегмента {cache} запись с Cache ID равным 'my_module'. cache_clear_all('my_module'); // Удаляет из сегмента {cache_example} записи, у которых // Cache ID начинается c 'my_module'. cache_clear_all('my_module', 'cache_example', TRUE);
Проверка на наличие данных в кэше
С помощью функции cache_is_empty можно узнать, хранятся ли в сегменте кэша какие-либо данные. Достаточно малоиспользуемая функция, но тем не менее помнить про неё надо.
Примеры использования
В качестве примера работы с кэшем вы можете установить модуль Cache Example, находящийся в составе модуля Examples.
- Spleshka
- 25.12.2012
- 13855