Back to Main Site

Управление кэшем: система кэширования на основе перехватчиков для разработчиков

Last updated on Jun 24, 2026 01:51

PolyCMS поставляется с централизованной системой Управления кэшем, которая предоставляет администраторам пользовательский интерфейс для проверки и очистки кешей, а также предоставляет разработчикам мощный управляемый API-интерфейс для интеграции их собственной логики кэширования без конфликта с ядром или другими модулями.

В этом руководстве описываются архитектура, доступные перехватчики и практические примеры для разработчиков модулей и тем, которые хотят расширять, заменять или реагировать на операции кэширования.

Обзор архитектуры

CacheService (app/Services/CacheService.php) — это единая точка входа для всех операций с кэшем. Он ведет реестр типов кэша, сгруппированных по четырем категориям:

Группа Описание Встроенные типы
laravel Laravel кэши фреймворка Приложение, Просмотр, Конфигурация, Маршрут, Событие
polycms Внутренние кэши сервисов PolyCMS Тема, модуль, настройки, преобразователь шаблонов
server Кэши уровня сервера PHP OPcache
module Зарегистрированные в модуле кэши (Здесь добавляется ваш модуль)

Система предоставляет 7 перехватчиков и фильтров, которые модули могут использовать для участия в управлении кэшем.

Справочник по перехватчикам и фильтрам

Фильтры (преобразователи значений)

Эти хуки позволяют модулям изменять данные перед их использованием.

cache.types — Регистрация пользовательских типов кэша

Добавляйте в систему свои собственные типы кэшей. Ваш тип появится на странице управления кэшем администратора рядом с основными типами.

Подпись: array $types

use App\Facades\Hook;

Hook::addFilter('cache.types', function (array $types) {
    $types[] = [
        'key'         => 'cdn_purge',
        'label'       => 'CDN Cache',
        'description' => 'Purge Cloudflare or Fastly edge cache',
        'group'       => 'module',   // Use 'module' for custom types
        'clearable'   => true,
    ];
    return $types;
});

Обязательные поля для каждого типа:

Поле Тип Описание
key string Уникальный фрагмент (используется в вызовах API)
label string Читабельное имя
description string Краткое объяснение, отображаемое в пользовательском интерфейсе администратора
group string laravel, polycms, server или module
clearable bool Должна ли появиться кнопка «Очистить»

cache.type.handler — Заявить право собственности на тип кэша

Это механизм предотвращения конфликтов. Когда модуль запрашивает тип кэша, ядро ​​пропускает свою собственную логику очистки для этого типа и полностью делегирует действие хуку действия cache.clear.{type} модуля.

Подпись: ?string $handler, string $type

Пример использования: вы создаете специальный модуль управления Redis и хотите обрабатывать кеш application иначе, чем стандартный php artisancache:clear.

Hook::addFilter('cache.type.handler', function (?string $handler, string $type) {
    if ($type === 'application') {
        return 'RedisManager'; // Your module name — core skips its clear logic
    }
    return $handler; // Return null for types you don't handle
}, 10, 2);

Когда установлен обработчик, в пользовательском интерфейсе администратора отображается значок, показывающий, какой модуль управляет этим типом кэша.

cache.status — Расширение данных о состоянии

Добавьте пользовательские метрики или диагностику в ответ о состоянии кэша.

Подпись: array $status

Hook::addFilter('cache.status', function (array $status) {
    // Add Redis memory info to the status payload
    $status['redis_info'] = [
        'used_memory_mb' => Redis::info()['used_memory_human'] ?? 'N/A',
        'connected_clients' => Redis::info()['connected_clients'] ?? 0,
    ];
    return $status;
});

Действия (обратные вызовы событий)

Эти перехватчики срабатывают в определенных точках жизненного цикла. Они не возвращают значения.

cache.clearing — перед очисткой типа

Срабатывает непосредственно перед очисткой любого типа кэша. Используйте для регистрации или предварительной очистки снимков.

Подпись: string $type

Hook::addAction('cache.clearing', function (string $type) {
    Log::info("Cache clear starting: {$type}");
});

cache.clear.{type} — Обработка очистки для определенного типа

Это основной способ реализации вашей собственной логики очистки. Если ваш модуль заявил тип через «cache.type.handler», именно здесь происходит фактическая работа.

Подпись: void

// Handle clearing for your custom CDN cache type
Hook::addAction('cache.clear.cdn_purge', function () {
    CloudflareApi::purgeEverything(config('services.cloudflare.zone_id'));
});

// Or override the core's application cache clearing
Hook::addAction('cache.clear.application', function () {
    Redis::connection('cache')->flushdb();
});

cache.cleared — После очистки типа

Срабатывает после очистки (или попытки) типа кэша с флагом успеха.

Подпись: string $type, bool $success

Hook::addAction('cache.cleared', function (string $type, bool $success) {
    if ($success) {
        Log::info("Cache cleared successfully: {$type}");
    } else {
        Log::warning("Cache clear failed: {$type}");
    }
}, 10, 2);

cache.clear_all.before / cache.clear_all.after

Срабатывает до и после операции массовой очистки (когда администратор нажимает «Очистить все кеши»).

Hook::addAction('cache.clear_all.before', function (array $types) {
    // $types = ['application', 'view', 'config', 'route', 'event', ...]
    Log::info('Bulk cache clear starting for: ' . implode(', ', $types));
});

Hook::addAction('cache.clear_all.after', function (array $results) {
    // $results = ['application' => 'success', 'view' => 'success', ...]
    $failed = array_filter($results, fn($r) => $r !== 'success');
    if (empty($failed)) {
        Log::info('All caches cleared successfully');
    }
});

Конечные точки REST API

Система управления кэшем предоставляет две аутентифицированные конечные точки API:

GET /api/v1/system/cache/status

Возвращает текущий статус всех зарегистрированных типов кэша.

Ответ:

{
  "data": {
    "driver": "file",
    "store": "file",
    "types": [
      {
        "key": "application",
        "label": "Application Cache",
        "description": "General key-value cache store",
        "group": "laravel",
        "clearable": true,
        "handler": null,
        "info": { "driver": "file" }
      },
      {
        "key": "view",
        "label": "View Cache",
        "group": "laravel",
        "clearable": true,
        "handler": null,
        "info": { "compiled_count": 75 }
      }
    ]
  }
}

POST /api/v1/system/cache/clear

Очистите один или несколько типов кэша.

Тело запроса:

{
  "types": ["view", "config", "theme"]
}

Или очистить все:

{
  "types": ["all"]
}

Ответ:

{
  "success": true,
  "results": {
    "view": "success",
    "config": "success",
    "theme": "success"
  },
  "message": "All selected caches cleared successfully."
}

Практические примеры

Пример 1: Модуль очистки CDN

Полный модуль, который регистрирует тип кэша CDN и выполняет его очистку:

// In your module's ServiceProvider boot() method

use App\Facades\Hook;

public function boot(): void
{
    // Register the cache type
    Hook::addFilter('cache.types', function (array $types) {
        $types[] = [
            'key'         => 'cdn',
            'label'       => 'CDN Edge Cache',
            'description' => 'Purge Cloudflare edge cache for all zones',
            'group'       => 'module',
            'clearable'   => true,
        ];
        return $types;
    });

    // Handle clearing
    Hook::addAction('cache.clear.cdn', function () {
        $zoneId = config('services.cloudflare.zone_id');
        $apiToken = config('services.cloudflare.api_token');

        Http::withToken($apiToken)
            ->post("https://api.cloudflare.com/client/v4/zones/{$zoneId}/purge_cache", [
                'purge_everything' => true,
            ]);
    });
}

Пример 2: Модуль полностраничного кэша (захватывающий ядро)

Модуль, который заменяет обработчик кэша приложения по умолчанию решением на основе Varnish:

public function boot(): void
{
    // Claim the 'application' cache type
    Hook::addFilter('cache.type.handler', function (?string $handler, string $type) {
        if ($type === 'application') {
            return 'VarnishCache';
        }
        return $handler;
    }, 10, 2);

    // Provide custom clearing logic
    Hook::addAction('cache.clear.application', function () {
        // Ban all objects from Varnish
        Http::withHeaders(['X-Purge' => '.*'])
            ->request('BAN', config('services.varnish.host'));

        // Also clear Laravel's cache store
        Artisan::call('cache:clear');
    });
}

Пример 3: Функции темы — автоматическая очистка при сохранении настроек

Тема, которая очищает свои собственные скомпилированные ресурсы при сохранении параметров темы:

// In themes/my-theme/functions.php

Hook::addAction('cache.cleared', function (string $type, bool $success) {
    if ($type === 'theme' && $success) {
        // Regenerate compiled theme CSS
        $css = MyTheme::compileStyles();
        file_put_contents(public_path('themes/my-theme/compiled.css'), $css);
    }
}, 10, 2);

Автоматическая очистка при загрузке темы

Когда тема загружается или обновляется через панель администратора, PolyCMS автоматически очищает следующие кеши:

Просмотр кэша — удаляет устаревшие скомпилированные шаблоны Blade.

Кэш конфигурации — обеспечивает загрузку новых определений настроек functions.php.

OPcache — Очищает кеш байт-кода PHP, поэтому новые файлы PHP компилируются заново.

Кэш темы — очищает внутренний реестр ThemeManager.

Кэш настроек — перезагружает автоматически загруженные настройки (включая новые параметры темы).

Кэш шаблонов — обновляет разрешение пути просмотра TemplateResolver.

Это устраняет распространенную проблему, когда новые параметры или представления темы не появляются после обновления темы.

Интерфейс администратора

Страница «Управление кэшем» доступна в Хаб настроек → Система → Кэш (или непосредственно в /admin/settings/cache). Он обеспечивает:

Информация о драйвере кэша вверху (файл, база данных, Redis и т. д.)

Сгруппированные карточки типов кэша, организованные по Laravel, PolyCMS, Server и Module.

Значки состояния, показывающие количество скомпилированных просмотров, состояния кэширования/некэширования, частоту попаданий OPcache.

Отдельные кнопки очистки для каждого типа кэша с указанием состояний загрузки.

Главная кнопка «Очистить все кеши»

Значки обработчиков, показывающие, какой модуль управляет конкретным типом.

Полная поддержка тёмного режима

Лучшие практики

Используйте cache.type.handler для предотвращения конфликтов. Если ваш модуль принимает тип кэша, всегда регистрируйте обработчик, чтобы ядро ​​и другие модули не вмешивались.

Обработчики cache.clear.{type} должны работать быстро. Администратор ожидает, что очистка кеша будет почти мгновенной. Для медленных операций (например, очистки CDN) рассмотрите возможность постановки задания в очередь и немедленного возврата.

Всегда возвращайте $handler в цепочке фильтров. Если вы проверяете cache.type.handler для определенного типа, всегда возвращайте исходный $handler для типов, которыми вы не управляете.

Группировать как «модуль». При регистрации пользовательских типов кэша используйте «группа» => «модуль», чтобы они отображались в разделе «Расширения модуля» пользовательского интерфейса администратора.

Записывайте события кэша. Используйте cache.clearing и cache.cleared для журналов аудита, особенно в производственных средах.

Похожие ресурсы

Хуки и фильтры: расширение ядра — изучите основы системы хуков PolyCMS.

Справочник по основным хукам и фильтрам — полный справочник всех ~90 хуков, доступных в ядре.

Разработка модулей: начало работы — Как создать модуль PolyCMS с нуля.