diff --git a/app/Console/Commands/ClearCacheByPattern.php b/app/Console/Commands/ClearCacheByPattern.php new file mode 100644 index 0000000..afea946 --- /dev/null +++ b/app/Console/Commands/ClearCacheByPattern.php @@ -0,0 +1,88 @@ +argument('pattern'); + $usePrefix = !$this->option('no-prefix'); + + // Получаем префикс кеша + $prefix = $this->getCachePrefix(); + + // Если префикс не пуст и мы его используем, добавляем к шаблону (если его там ещё нет) + if ($usePrefix && $prefix !== '' && strpos($pattern, $prefix) !== 0) { + $pattern = $prefix . $pattern; + $this->line("Добавлен префикс конфига: '{$prefix}'"); + } + + $this->line("Итоговый шаблон: {$pattern}"); + + // Проверка на отсутствие * (только если это не точный ключ) + if (strpos($pattern, '*') === false) { + if (!$this->confirm("Шаблон не содержит '*', будет удалён только один конкретный ключ. Продолжить?")) { + return 0; + } + } + + if (!$this->option('force') && !$this->confirm("Удалить все ключи по шаблону '{$pattern}'?")) { + return 0; + } + + $deleted = 0; + $cursor = 0; + + $this->info("Начинаю поиск..."); + + do { + $result = Redis::scan($cursor, ['match' => $pattern, 'count' => 200]); + + if ($result === false) { + $this->info("Ключи по шаблону '{$pattern}' не найдены!"); + return 0; + } + + $cursor = $result[0]; + $keys = $result[1]; + + if (!empty($keys)) { + Redis::del($keys); + $deleted += count($keys); + $this->line("Удалено {$deleted} ключей..."); + } + } while ($cursor != 0); + + $this->info("Готово! Удалено ключей: {$deleted}"); + return 0; + } + + /** + * Получает префикс кеша из конфигурации Laravel. + * + * @return string + */ + private function getCachePrefix(): string + { + // Сначала пытаемся взять префикс для хранилища redis + $prefix = config('cache.stores.redis.prefix'); + + // Если не задан, берём глобальный префикс (если есть) + if ($prefix === null) { + $prefix = config('cache.prefix', ''); + } + + // Приводим к строке и обрезаем лишние пробелы + return trim((string) $prefix); + } +}