Кеширование данных в Битрикс D7: простой, управляемый и ORM
Зачем отдельно разбирать кеш в D7
В старых проектах часто встречается CPHPCache и разрозненные обёртки. В D7 кеширование унифицировано: один стиль API, управляемый кеш с тегами и встроенная поддержка в ORM. Ниже — практические паттерны, которые можно сразу перенести в модуль или компонент.
Простой кеш: \Bitrix\Main\Data\Cache
Класс \Bitrix\Main\Data\Cache — прямой наследник идеи CPHPCache. Отличия в основном в именовании методов (CamelCase) и строгой типизации.
use Bitrix\Main\Data\Cache;
$cache = Cache::createInstance();
$cacheTtl = 7200;
$cacheId = 'catalog_sections_tree_v1';
$cacheDir = '/my_module/catalog';
if ($cache->initCache($cacheTtl, $cacheId, $cacheDir)) {
$sections = $cache->getVars();
} elseif ($cache->startDataCache()) {
$sections = loadSectionsFromDb(); // тяжёлая логика
$cache->endDataCache($sections);
}Параметры initCache():
- TTL — время жизни в секундах;
- uniqueString — уникальный ключ (добавляйте версию схемы данных:
_v2); - initDir — подпапка в
/bitrix/cache/; - baseDir — по умолчанию
cache.
Совет: не кешируйте объекты с ресурсами (соединения, файловые дескрипторы). Сохраняйте массивы и скаляры.
Управляемый кеш (ManagedCache)
Управляемый кеш автоматически сбрасывается при событиях ядра (изменение инфоблока, настроек и т.д.), если вы связали данные с тегами. Получить экземпляр:
$managedCache = \Bitrix\Main\Application::getInstance()->getManagedCache();
$cacheId = 'iblock_5_sections_list';
$cacheTtl = 3600;
if ($managedCache->read($cacheTtl, $cacheId)) {
$sections = $managedCache->get($cacheId);
} else {
$sections = loadSectionsFromDb();
$managedCache->set($cacheId, $sections);
}Принудительная очистка по ключу:
$managedCache->clean($cacheId);Для инфоблоков удобно комбинировать с CIBlock::registerWithTagCache() или тегированным кешом компонентов — тогда сброс произойдёт при сохранении элемента без ручного clean().
Кеширование ORM-выборок
Начиная с версии 16.5.9, в getList() можно передать параметр cache. Пример для элементов инфоблока через ElementTable:
use Bitrix\Iblock\ElementTable;
$query = ElementTable::getList([
'select' => ['ID', 'NAME', 'CODE'],
'filter' => ['IBLOCK_ID' => 5, 'ACTIVE' => 'Y'],
'order' => ['SORT' => 'ASC'],
'cache' => [
'ttl' => 300,
'cache_joins' => true,
],
]);
while ($row = $query->fetch()) {
// ...
}Кеш пишется в /bitrix/managed_cache/MYSQL/orm_* с ключом по SQL-запросу. Параметр cache_joins включает кеширование запросов с JOIN — используйте осознанно, если выборка тяжёлая.
Глобальные ограничения TTL для таблиц задаются в /bitrix/.settings.php:
'cache_flags' => [
'value' => [
'b_iblock_element_min_ttl' => 60,
'b_iblock_element_max_ttl' => 86400,
],
],Инвалидация кеша ORM
После массового импорта или миграции сбросьте кеш сущности:
\Bitrix\Iblock\ElementTable::getEntity()->cleanCache();Для своих ORM-сущностей — тот же метод у YourTable::getEntity().
Что выбрать на практике
| Сценарий | Инструмент |
|---|---|
| Результат тяжёлого PHP-расчёта | Data\Cache |
| Данные, связанные с инфоблоками/настройками | ManagedCache + теги |
| Частые однотипные выборки ORM | cache в getList() |
| Вывод в компоненте | Кеш компонента + тегированный кеш |
Типичные ошибки
- Один ключ кеша для разных языков/сайтов — добавляйте
SITE_IDиLANGUAGE_IDвcacheId. - Кеширование персональных данных (корзина, профиль) — только с привязкой к ID пользователя в ключе.
- Забыли сбросить кеш после деплоя с изменением структуры — увеличивайте версию в ключе.
Итог
D7 даёт три уровня кеширования без сторонних библиотек. ManagedCache удобен для справочников и настроек, параметр cache в ORM — для стабильных выборок, а Data\Cache — для тяжёлых PHP-расчётов вне компонентов.