Кэш для PHP 8.1+: PSR-16 и PSR-6 из одного пакета, remember со stampede-защитой (XFetch), теги с O(1)-инвалидацией, пространства имён, цепочки L1/L2, LRU-лимит, нативные счётчики с сохранением TTL, статистика, prune, детерминированный TTL в тестах (PSR-20). Бэкенды: память, файлы с атомарной записью

Maintainers

Package info

gitverse.ru/cloud-castle/cache

Homepage

Issues

Documentation

pkg:composer/cloud-castle/cache

Transparency log

Statistics

Installs: 18

Dependents: 4

Suggesters: 2

v1.2.2 2026-08-05 06:42 UTC

README

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano

CloudCastle Cache

CloudCastle Cache

Packagist Version Downloads Monthly Downloads PHP Version License

Source Release Issues CI

PHPStan Psalm PHPMD PHPCS Coverage Infection MSI OpenSSF Scorecard

Кэш для PHP 8.1+, закрывающий PSR-16 и PSR-6 одним пакетом и превосходящий по возможностям сумму популярных аналогов: remember со stampede-защитой (XFetch), теги с O(1)-инвалидацией, изолированные пространства имён, многоуровневые цепочки L1/L2, LRU-лимит памяти, нативные счётчики с сохранением TTL, статистика hits/misses, prune() и детерминированный TTL в тестах через инъектируемые часы (PSR-20). Бэкенды: память, файлы с атомарной записью, Redis и Memcached (клиенты cloud-castle/redis и cloud-castle/memcached); безопасная сериализация cloud-castle/serialize — белые списки классов и HMAC-подпись записей. И всё это быстрее всех сравниваемых библиотек.

Установка

composer require cloud-castle/cache

Требуется PHP 8.1+. Серверные бэкенды подключаются по потребности: composer require cloud-castle/redis (RedisStore) и/или composer require cloud-castle/memcached (MemcachedStore) — ядро пакета не тянет их в зависимости.

Быстрый старт

<?php

use CloudCastle\Cache\Cache;

// PSR-16 (SimpleCache) в памяти; file('/dir') — на диске с атомарной записью.
$cache = Cache::array();
$cache->set('user.42', $user, 3600);
$user = $cache->get('user.42', $default);

// PSR-6 (CacheItemPool) над тем же бэкендом.
$pool = Cache::filePool('/var/cache/app');
$item = $pool->getItem('report');
if (!$item->isHit()) {
    $pool->save($item->set($report)->expiresAfter(600));
}

// Репозиторий: remember + защита от cache stampede (XFetch), счётчики, статистика.
$repo = Cache::repository($cache);
$report = $repo->remember('report', 300, fn () => $api->build(), beta: 1.0);
$repo->increment('report.views');                 // TTL записи сохраняется
$ratio = $repo->stats()->hitRatio();

// Теги: O(1)-инвалидация связанных записей без перебора данных.
$cache->tags('users', 'reports')->set('report.42', $report, 3600);
$cache->invalidateTags('users');

// Изолированные пространства имён: свой clear, никаких пересечений.
$sessions = $cache->withNamespace('sessions');
$sessions->clear();                               // остальной кэш не тронут

// L1/L2: память перед файлами, найденное проливается вверх.
$fast = Cache::chain([$memoryStore, $fileStore], promoteTtlSeconds: 60);

// Детерминированный TTL в тестах: MockClock вместо реального ожидания.
$cache = Cache::array($mockClock);

// Redis: кластер/sentinel/TLS — в клиенте cloud-castle/redis; TTL исполняет сервер,
// инкременты атомарны между процессами (INCRBY), пространства имён — префиксы.
$redis = Cache::simple(new RedisStore(new \CloudCastle\Redis\Client('redis://127.0.0.1:6379/1')));

// Memcached: шардирование/SASL/TLS — в клиенте cloud-castle/memcached;
// пространства имён — версионные префиксы (очистка одним инкрементом версии).
$memcached = Cache::simple(new MemcachedStore($memcachedClient));

// Строгая десериализация: белый список классов или HMAC-подпись записей.
$audited = Cache::simple(new FileStore('/var/cache/app', $clock, Serializer::php([Report::class])));

Возможности

  • PSR-16 + PSR-6 из одного пакета над общим бэкендом (SimpleCache, CacheItemPool).
  • remember / rememberForever с вероятностной stampede-защитой XFetch (beta) — толпа запросов не обрушивается на бэкенд в момент истечения (Repository).
  • Теги с O(1)-инвалидацией по версиям — записи не перебираются (TaggedCache).
  • Изолированные пространства имён: свой clear(), на файлах — подкаталоги (NamespaceCapable).
  • Многоуровневые цепочки L1/L2 с проливкой найденного вверх (ChainStore).
  • LRU-лимит записей в памяти — кэш не разрастается бесконтрольно (ArrayStore).
  • Нативные increment/decrement с сохранением TTL записи (IncrementCapable).
  • pull / add / forever и статистика hits/misses/writes/deletes из коробки.
  • prune() — целевая уборка просроченного (Pruneable).
  • Инъектируемые часы (PSR-20): истечение TTL детерминировано в тестах — «перемотка» времени без ожидания.
  • Атомарная файловая запись (temp + rename): конкурентные чтения не видят битых файлов.
  • Бэкенд Redis (RedisStore) поверх cloud-castle/redis (кластер, sentinel, TLS): TTL исполняет сервер, инкременты атомарны между процессами, очистка пространства — SCAN по префиксу.
  • Бэкенд Memcached (MemcachedStore) поверх cloud-castle/memcached (ketama, SASL, TLS): версионные пространства имён — очистка одним атомарным инкрементом версии, мгновенно видимая всем процессам.
  • Безопасная сериализация (NativePhpSerializer, SealedSerializer): в файловое и Redis-хранилище инъектируется любой сериализатор cloud-castle/serialize — белый список классов против POP-цепочек или HMAC-подпись записей против подмены на носителе.
  • Безопасность по умолчанию: PSR-валидация ключей, SHA-256-имена файлов (без traversal), строгая валидация имён пространств, служебные ключи недостижимы для пользовательских записей.
  • Нулевые тяжёлые зависимости — только PSR-контракты и лёгкие cloud-castle/clock, cloud-castle/file-system, cloud-castle/serialize; клиенты Redis/Memcached — опциональные suggest-пакеты.

Сравнение с аналогами

Все таблицы ниже сгенерированы автоматически из честных сравнительных тестов (benchmarks/compare.php) на ОДИНАКОВОЙ операции для всех аналогов, PHP 8.3.33, без Xdebug.

1. Функциональность

Возможность🏆 CloudCastlesymfonyscrapbookilluminatephpfastcachestash²laminasarray¹
PSR-16 (SimpleCache) из коробки
PSR-6 (CacheItemPool) из коробки
Инъектируемые часы (PSR-20) — детерминированный TTL в тестах
Атомарная файловая запись (temp + rename, без битых кэш-файлов)
remember / rememberForever (вычислить при промахе)
pull / add / forever (высокоуровневые операции)
Нативный инкремент с сохранением TTL записи
Теги с O(1)-инвалидацией по версиям
Изолированные пространства имён (включая изолированный clear)
Многоуровневая цепочка L1/L2 с проливкой вверх
LRU-вытеснение в памяти (лимит записей/байт)
Stampede-защита из коробки (XFetch/beta/lock)
Счётчики hits/misses/writes/deletes из коробки
prune() — целевая уборка просроченных записей
Бэкенд Redis из коробки
Бэкенд Memcached из коробки
Подключаемая безопасная десериализация (белый список классов, HMAC)
Всего🏆 1713786870

2. Безопасность и корректность

Свойство🏆 CloudCastlesymfonyscrapbookilluminatephpfastcachestash²laminasarray¹
Валидация ключей по PSR (запрет {}()/\@:)
Корректное хранение null (отличается от промаха)
Атомарная запись файлов (нет частичных данных)
Детерминированное истечение TTL (инъектируемые часы)
Устойчивость к битым кэш-файлам (промах вместо падения)
Имена файлов — хэш ключа (path traversal исключён)
Строгая валидация имён пространств (защита от ../)
Служебные ключи недостижимы для пользовательских записей
HMAC-подпись кэш-нагрузок от подмены на носителе
Белый список классов при десериализации (анти-POP)
Всего🏆 106324320

3. Производительность

set + get в кэше «в памяти», 200 000 раз (минимум из 4).

РешениеВремя (мс)Итог
array¹6,8базовый уровень (не библиотека)
🏆 CloudCastle170,3быстрейшее среди библиотек
illuminate220,1аналог
symfony502,6аналог
scrapbook579,6аналог
phpfastcache734,8аналог
stash²1 016,8аналог
laminas1 743,7аналог

4. Потребление памяти

Память самой библиотеки (классы + структуры данных) на 200 000 операций: пик рабочей фазы минус baseline, снятый до создания кэша в изолированном процессе, — стоимость PHP и автолоадера вычтена.

РешениеПиковая память (KB)Итог
array¹1базовый уровень (не библиотека)
🏆 scrapbook150легчайшее среди библиотек
illuminate153аналог
symfony186аналог
CloudCastle191аналог
stash²231аналог
phpfastcache931аналог
laminas1 575аналог

5. Утечки памяти

_Рост памяти за 100 000 операций после прогрева и gc_collectcycles (изолированный процесс, только целевая библиотека; 0 — утечек нет).

РешениеРост памяти (KB)Итог
🏆 CloudCastle0без утечек, стабильнее всех
symfony0аналог
scrapbook0аналог
illuminate0аналог
phpfastcache0аналог
stash²0аналог
laminas0аналог
array¹0базовый уровень (не библиотека)

6. Качество кода

Машинно-измеримые метрики исходников каждого пакета (жирным — лучшее значение строки).

Метрика🏆 CloudCastlesymfonyscrapbookilluminatephpfastcachestash²laminas
Синтаксические ошибки (phplint)0000000
Файлы со strict_types, %1000100099019
final-классы, %1009001054
Runtime-зависимостей5524217
Файлов исходников288840441423374
Требование PHP>=8.1>=8.1>=8.0.0^8.1>=8.0^8.0~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0
Всего побед🏆 4121121

¹ Базовый уровень (нативные вызовы/примитивы без полноты решения) показан для контекста и не претендует на победу среди библиотек-аналогов. ² Stash не реализует PSR-16 — выполняется эквивалентная работа его родным PSR-6 пулом (getItem/set/save + getItem/get).

Вывод: CloudCastle Cache — самый быстрый среди сравниваемых библиотек и единственный, кто закрывает весь набор: PSR-16 + PSR-6, remember со stampede-защитой, теги, пространства имён, цепочки, LRU, счётчики, статистику, prune, тестируемый TTL, бэкенды Redis/Memcached и строгую десериализацию — при атомарной файловой записи. По памяти самой библиотеки — компромисс п. «потребление памяти» (см. ограничения ниже): на десятки килобайт тяжелее самого лёгкого аналога, покрывающего в 2–3 раза меньше возможностей.

Честно о плюсах и минусах

Сильные стороны:

  • один пакет вместо связки «кэш + хелперы + инвалидация» — суперсет возможностей symfony/illuminate при минимальных зависимостях;
  • быстрейший get/set среди сравниваемых библиотек; память без утечек (0 KB роста под нагрузкой);
  • уникально: детерминированный TTL в тестах (PSR-20 часы) и строгая изоляция пространств имён с защитой от path traversal;
  • 100 % покрытие строк и MSI 100 % (все мутанты убиты) — поведение зафиксировано тестами полностью.

Ограничения:

  • клиенты Redis/Memcached — отдельные пакеты (suggest, не жёсткие зависимости): для серверных бэкендов доустановите cloud-castle/redis и/или cloud-castle/memcached (до их релизов 1.0.0 в require-dev пакета используются dev-срезы);
  • межпроцессная атомарность add/increment на файлах не гарантируется (гонка «оба записали» допустима и задокументирована; на Redis инкремент межпроцессно атомарен нативно, на Memcached — нативная арифметика с клампом декремента на нуле) — для распределённых блокировок нужен внешний lock-механизм;
  • теги и stampede-мета добавляют по служебной записи — на файловом бэкенде это дополнительные файлы (учитывайте при жёстких лимитах inode);
  • память самой библиотеки (классы + структуры) — место в середине таблицы (см. «Потребление памяти» выше): на десятки килобайт тяжелее самого лёгкого аналога (scrapbook) — осознанная цена суперсета возможностей (компромисс допускается приоритетами проекта); стоимость процесса PHP и автолоадера у всех библиотек одинакова.

Где применять:

  • Веб-приложения и API (один сервер) — файловый кэш с атомарной записью и тегами: сброс по сущностям без полного flush.
  • CLI, воркеры, тесты — кэш в памяти с LRU-лимитом; MockClock делает TTL-сценарии детерминированными.
  • Горячие вычисленияremember(..., beta: 1.0) вместо самодельных блокировок: XFetch размазывает пересчёт по времени.
  • Микросервисы с локальным L1Cache::chain([память, файлы]): чтения идут из памяти, рестарт переживается за счёт файлового уровня.
  • Общий кэш нескольких серверовRedisStore/MemcachedStore (плюс локальный L1 через Cache::chain([память, Redis])): теги, пространства, счётчики и remember работают поверх серверных бэкендов так же, как поверх файлов.
  • Кэш на разделяемом/недоверенном носителеSealedSerializer (HMAC-подпись) или белый список классов: подменённая запись отвергается и удаляется, а не исполняется.

Разработка

composer install
composer check       # линтеры + статический анализ + тесты
composer fix         # автоисправления (Rector, PHP CS Fixer, PHPCBF)
composer ci          # полный CI-пайплайн локально
composer test:full   # phplint → psalm → phpstan → phpmd → phpcs → rector →
                     # deptrac → мутации → безопасность → память → утечки →
                     # производительность → качество (гейт превосходства)
composer docs:build  # сравнительные бенчмарки + генерация таблиц

Полный список команд с описаниями: composer run-script --list.

Документация

Лицензия

MIT © CloudCastle (alex-4-17@yandex.ru)

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano