Удаление из кеша 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);
}