Detect if Cache Driver Supports Tags

2019-06-18 23:03发布

Is there a clean way to determine if the current Cache engine supports tags in Laravel? We're relying on an open source module/ServiceProvider that needs tags support, and I want to make sure our system is bullet proof such that switching the cache engine won't cause fatal errors.

Right now, if a user has a system configured with the file or database caching engines, the following code

Cache::tags([]);

throws an error

Illuminate\Cache\FileStore does not have a method tags

If a user has a system configured with something like memcached or redis, the code works without issue.

Is there a way to cleanly detect if the currently configured cache engine supports tags? The best I've been able to come up with is

$app = app();
$has_tags = method_exists($app['cache']->driver()->getStore(), 'tags');

but that's making a lot of assumptions w/r/t to there being a cache service configured, and that the cache service users a "driver", that the driver users a "store", and that the tags method isn't there fore another purpose.

I've also thought about wrapping the call to Cache::get in a try/catch, but then I'm relying on Laravel's "throw an exception for a PHP error" behavior not changing in a future version.

Is there an obvious solution I'm missing?

3条回答
疯言疯语
2楼-- · 2019-06-18 23:29

If you'd like to generate a list of the stores that support tagging, use this:

$stores = collect(config('cache.stores'))
    ->keys()
    ->flatMap(function ($type) {
        return [
            $type => Cache::store($type)->getStore() instanceof Illuminate\Cache\TaggableStore,
        ];
    });

These are the answers for the default cache stores (on 5.2 installation, other versions seem the same):

  • apc: true
  • array: true
  • database: false
  • file: false
  • memcached: true
  • redis: true
查看更多
ゆ 、 Hurt°
3楼-- · 2019-06-18 23:32

I know this is an old question, but for anyone else arriving here, the correct answer would be:

if(Cache::getStore() instanceof \Illuminate\Cache\TaggableStore;) {
    // We have a taggable cache.
}
查看更多
何必那么认真
4楼-- · 2019-06-18 23:34

While the other answers work for the built-in cache drivers I've used a tagged file cache driver which has a store that unfortunately does not extend TaggableStore

The only way I could get this to work was by doing:

 if (method_exists(Cache::store($type)->getStore(), 'tags')) {
    // Supports tags
 }

Reason is (I'm guessing) that TaggableStore is an abstract class and not an interface so it kind of limits the options.

查看更多
登录 后发表回答