2013-02-14 2 views
12

Для моего пакета мы используем кэш Laravel,Удаление из кеша Laravel 4 с использованием шаблона для ключа?

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

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

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

ответ

10

Easy - использовать Cache::getMemory()

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

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

+1

Просто к сведению, с кэш-файлов и Redis, используя Laravel 4, это не работает. он говорит, что метод getMemory() не найден. – Arda

+3

getMemory() доступен только для memcache – Bala

+2

: это «ошибка»: {«type»: «ErrorException», «message»: «call_user_func_array() ожидает, что параметр 1 является допустимым обратным вызовом, класс« Illuminate \\ Cache » \\ MemcachedStore 'не имеет метода «getMemory», «file»: «\/Users \/ericcumbee \/Desktop \/phpprojects \/sblitz \/vendor \/laravel \/framework \/src \/Illuminate \ /Cache\/Repository.php "," строка ": 277}' ошибка для меня в Laravel 4.2 с помощью memcached – gsueagle2008

14

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

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

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) не будет конфликтовать с вашими.

6

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

с помощью клавиш

$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; 
} 
+1

использование 'KEYS' сильно обескуражено, так как это команда O (N) (т. Е. Вы можете запустить DoS, запустив ее, а также исчерпав RAM вашего сервера при подготовке буфера ответа). Начиная с версии 2.0 рекомендуемый подход заключается в использовании команды SCAN. –

1

Вот 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); 
}