14

For my package we make use of the Laravel cache,

Every cache key we create is prefixed, so we get mypackage-config, mypackage-md5ofafilename At times I need to flush all cache files that my package has created, the issue? I only know the pattern of the cache keys, I don't know the entire key!

So, I need a way to go Cache::forget('mypackage-*') or similar, is this possible?

If it was just for my system I know I am using the file cache, so I could manually unlink the files, but because it is a generic package I don't know what cache method the end user is using, I just know the interface (aka the Laravel cache interface).

4 Answers 4

17

Another solution: as long as you are not using file or database cache you can make use of Cache Tags.

Just tag every cache entry with your package name:

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

(You can also use the tags method with remember, forever, and rememberForever)

When it's time to flush the cache of your package's entries just do

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

Note: When you need to access the cache entries you still need to reference the tags. E.g.

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

That way, another cache entry with key config having a different tag (e.g. hisPackage) will not conflict with yours.

Sign up to request clarification or add additional context in comments.

Comments

12

Easy - use Cache::getMemory()

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

p.s. dont ever unlink 'cache' files manually. Laravel cache keeps a record of all cache records in an array, so it will be expecting the file to be there, even if you 'unlink' it.

4 Comments

Just to note, with file cache and Redis, using Laravel 4, this does not work. it says getMemory() method is not found.
getMemory() is available for memcache only
this throws a "error":{"type":"ErrorException","message":"call_user_func_array() expects parameter 1 to be a valid callback, class 'Illuminate\\Cache\\MemcachedStore' does not have a method 'getMemory'","file":"\/Users\/ericcumbee\/Desktop\/phpprojects\/sblitz\/vendor\/laravel\/framework\/src\/Illuminate\/Cache\/Repository.php","line":277} error for me in Laravel 4.2 using memcached
A bit late, but... getMemory() isn't supported any more.
7

Here is the same solution as in the accepted answer, but rewritten specifically for Redis.

Using KEYS

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

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

Using 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 Comment

the use of KEYS is highly discouraged as it is an O(N) command (i.e. you could trigger a DoS by running it as well as exhausting your server's RAM in preparing the reply's buffer). As of v2.8 the recommended approach is to use the SCAN command.
2

Here is a Redis specific example to clear all keys based on a given prefix. This is based on Kazik's answer, with some restructuring and added safety.

Note that RedisStore is under the namespace 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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.