Сброс кеша инфоблока при изменении связанного highload-блока (D7)
Когда это нужно
Типичный кейс: в инфоблоке хранятся «основные» материалы, а в highload — служебные справочники (флаги, подписи, привязки), из которых собирается финальный HTML в компонентах. Компоненты кешируют результат и помечают запись тегами вида iblock_id_N. Пока меняется только HL, ядро само по себе не обязано трогать кеш инфоблока — отсюда рассинхрон: в админке данные уже другие, на витрине ещё старый фрагмент.
Идея решения
Для каждой сущности highload в рантайме регистрируются события …OnAfterAdd, …OnAfterUpdate, …OnAfterDelete. Префикс совпадает с именем класса сущности из настроек блока (латиница, без пробелов). В обработчике достаточно сбросить тег кеша инфоблока, который используют ваши компоненты — через глобальный $GLOBALS['CACHE_MANAGER'] и метод ClearByTag().
Пример
Пусть инфоблок имеет ID 36, а highload с таблицей/сущностью в админке описан классом VideoS4 — тогда строки событий будут начинаться с VideoS4OnAfter…. Подставьте свои числа и имя сущности из проекта.
namespace Partner;
use Bitrix\Main\EventManager;
use Bitrix\Main\Entity\Event;
class Video
{
/** Сброс компонентного кеша, привязанного к инфоблоку 36 */
public static function invalidateLinkedIblockCache(Event $event): void
{
$cache = $GLOBALS['CACHE_MANAGER'] ?? null;
if ($cache instanceof \CCacheManager) {
$cache->ClearByTag('iblock_id_36');
}
}
}
$em = EventManager::getInstance();
$em->addEventHandler('', 'VideoS4OnAfterAdd', [Video::class, 'invalidateLinkedIblockCache']);
$em->addEventHandler('', 'VideoS4OnAfterUpdate', [Video::class, 'invalidateLinkedIblockCache']);
$em->addEventHandler('', 'VideoS4OnAfterDelete', [Video::class, 'invalidateLinkedIblockCache']);Имя тега должно совпадать с тем, под которым реально кешируется вывод: для стандартных компонентов инфоблока чаще всего достаточно iblock_id_<ID>. Если вы вручную регистрировали теги в своём коде — сбрасывайте их же.
Замечания по внедрению
- Имя события берётся из кода сущности HL в настройках, а не из человекочитаемого названия блока. При сомнении посмотрите список обработчиков или событий модуля
mainв отладчике. - Несколько инфоблоков — вызовите
ClearByTagдля каждого затронутого тега или заведите свой общий тег в пользовательском кешировании и сбрасывайте его из HL. - Связка с компонентным кешем — при использовании
CIBlock::registerWithTagCache()в своих выборках теги могут отличаться; ориентируйтесь на фактическую регистрацию в шаблоне.
См. также по теме кеша
Общие приёмы тегированного кеша и работы с Data\Cache в D7 полезно держать под рукой рядом с точечными сбросами по highload.
Не хотите копаться сами?
Починю за 1-3 дня. Без предоплаты — оплата по результату.
15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии