Удаление из кеша Laravel 4 с использованием шаблона для ключа?

Для моего пакета мы используем кеш Laravel,

Каждый создаваемый нами кеш-ключ имеет префикс, поэтому мы получаем mypackage-config, mypackage-md5ofafilename Иногда мне нужно очистить все файлы кеша, созданные моим пакетом, проблема? Я знаю только тип ключей кеша, я не знаю весь ключ!

Итак, мне нужен способ пойти Cache::forget('mypackage-*') или аналогичный, возможно ли это?

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

Ответ 1

Простота использования Cache::getMemory()

foreach (Cache::getMemory() as $cacheKey => $cacheValue)
{
    if (strpos($cacheKey, 'mypackage') !== false)
    {
        Cache::forget($cacheKey);
    }
}

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

Ответ 2

Другое решение: до тех пор, пока вы не используете кеш файлов или баз данных, вы можете использовать Теги кэша.

Просто помечайте каждую запись кэша с именем вашего пакета:

Cache::tags('myPackage')->put('config', $config, $minutes);
Cache::tags('myPackage')->put('md5ofafilename', $md5, $minutes);

(Вы также можете использовать метод tags с remember, forever и rememberForever)

Когда пришло время сбросить кеш ваших записей пакета, просто

Cache::tags('myPackage')->flush();

Примечание: Когда вам нужно получить доступ к записям кэша, вам все равно нужно ссылаться на теги. Например.

$myConfig = Cache::tags('myPackage')->get('config');

Таким образом, другая запись кэша с ключом config с другим тегом (например, hisPackage) не будет конфликтовать с вашим.

Ответ 3

Вот то же самое решение, что и в принятом ответе, но переписано специально для Redis.

Использование KEYS

$redis = Cache::getRedis();
$keys = $redis->keys("*");

foreach ($keys as $key) {
  if (strpos($key, 'mypackage') !== false)
  {
    $redis->del($key);
  }
}

Использование SCAN (Redis >= 2.8.0)

$redis = Cache::getRedis();
$cursor = 0;

while($data = $redis->scan($cursor))
{
  $cursor = $data[0];

  foreach($data[1] as $key)
  {
    if (strpos($key, 'mypackage') !== false)
      {
        $redis->del($key);
      }
    }
  }

  if ($cursor == 0) break;
}

Ответ 4

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

Обратите внимание, что RedisStore находится под пространством имен Illuminate\Cache\RedisStore

$cacheDriver = Cache::driver();
if ($cacheDriver instanceof(RedisStore)) {
    $cursor = 0;
    do {
        $data = $cacheDriver->scan($cursor);
        $cursor = $data[0];
        $cacheEntries = $data[1];

        foreach ($cacheEntries as $key) {
            // This clears based on prefix. Change according to your use case.
            if (starts_with($key, Cache::getPrefix())) {
                $redis->del($key);
            }
        }

    } while ($cursor != 0);
}