89 lines
3.3 KiB
PHP
89 lines
3.3 KiB
PHP
<?php
|
||
|
||
namespace App\Console\Commands;
|
||
|
||
use Illuminate\Console\Command;
|
||
use Illuminate\Support\Facades\Redis;
|
||
|
||
class ClearCacheByPattern extends Command
|
||
{
|
||
protected $signature = 'cache:clear-pattern {pattern : Шаблон ключей, например "doctors:duty:*" }
|
||
{--force : Удалять без подтверждения}
|
||
{--no-prefix : Не добавлять автоматически префикс из конфига}';
|
||
|
||
protected $description = 'Удаляет все ключи Redis, соответствующие шаблону (с автоподстановкой префикса)';
|
||
|
||
public function handle()
|
||
{
|
||
$pattern = $this->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);
|
||
}
|
||
}
|