Yandex Metrika
sanches.free 1 просмотр

Сброс кеша инфоблока при изменении связанного 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 дней гарантии