12

In Laravel you can place items in the Cache with a tag like:

Cache::tags('bans')->put($result->ip, $result->reason);

But I can't seem to find a way to get all items with a certain tag. Is it possible to retrieve all items with a certain tag?

Like:

Cache::tags('bans')->all(); 

Or something like that

Matthijn
  • 3,126
  • 9
  • 46
  • 69

4 Answers4

9

The underlaying Cache Drive is not supported retrieve all caches of a certain tag.

If u really need this kind of feature, u should looking for Redis, using Redis' hash instead of Cache's tags.

Here is some example code:

// Delete hash table - `bans`
Redis::del('bans');
// Setting hash table filed
Redis::hSet('bans', 'ip1', 'spam: test reason');
Redis::hSet('bans', 'ip2', 'spam: test reason 2');
// Get all filed form hash table - `bans`
dd(Redis::hGetAll('bans'));

Debug output will be:

array:2 [▼
  "ip1" => "spam: test reason"
  "ip2" => "spam: test reason 2"
]
CharlieJade
  • 1,173
  • 14
  • 10
4

I think you use it wrong. As first argument you pass key of cache, as second value and as third expire time in minutes.

If you want to cache some bans with reason, for example assume you have in PHP some group of users who spammed, you could use something like that:

$bans = [
   [
       'ip' => 'test ip',
       'reason' => "spam: test reason",
   ],
   [
       'ip' => 'test ip2 ',
       'reason' => "spam: test reason 2",
   ]

];

Cache::tags('bans')->put('spam', $bans, 100);

$spams = Cache::tags('bans')->get('spam');
foreach ($spams as $spam) {
    echo $spam['ip'].' '.$spam['reason']."<br />";
}

So here you put into cache the whole array and now you can access items using standard foreach loop.

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
  • 23
    Is there no way to do something like `Cache::tags([$tag])->all();`? I have a very specific use case where I need to be able to retrieve every item from the cache that has a specific tag. – Vigs Jul 06 '15 at 01:50
  • 5
    I want to do the same as the question asker. But I've never found docs about how to retrieve all caches of a certain tag. Does that mean that tags are only helpful for *deleting* multiple caches at once? In the example above, the tags seem useless. How is `$spams = Cache::tags('bans')->get('spam');` different from `$spams = Cache::get('spam');`? – Ryan Apr 03 '17 at 13:03
2

In 'yourKeyGoesHere' you can insert a string used as same as a like with a * or insert directly the exactly key.

$redis = Cache::getRedis();
$a_keys = $redis->keys("*yourKeyGoesHere*");
nat_jea
  • 285
  • 3
  • 5
0

Laravel stores all tagged items in one Redis Set. So after:

Cache::tags('bans')->put($result->ip, $result->reason);

Laravel creates tag:bans:key –  which in itself stores just a key to the Set with all tagged items.

$setKey = Cache::get('tag:bans:key'); // => 63bd57cbdb77d819804950 – key to the Set that contains all tagged items

Now we can get all items using that key:

// get all set members
$keys = Cache::connection()->smembers("prefix:$setKey:forever_ref");

$items = [];
foreach($keys as $key) {
  $key = collect(explode(':', $key))->last(); // remove prefix from $key
  $items[] = Cache::tags('bans')->get($key);
}
Deez
  • 43
  • 1
  • 5
Max Flex
  • 1,116
  • 10
  • 16