3分钟短文:说说Laravel通用缓存Cache的使用技巧

简介: 用户缓存 Session 与 全局缓存 Cache

引言

前一期我们介绍了存储用户会话数据到服务器,并通过框架提供的Session类
进行数据读写操作的方法。

图片

但是有些数据,如数据库集合,API接口等等,对于全局的用户来说是无差别的,
这时候我们需要全局缓存以便提供给所有的用户使用。

本期就来说说Cache缓存。

代码时间

laravel在设计上做了很巧妙的构思,将缓存相关的类,设计得有插接件的感觉。
所以,你看到Session Cache Cookie 这些缓存数据类,基本上除了底层的驱动,
数据结构,过期特性等等,都集成了系统数组类Arr的操作方法。所以上述三种缓存在
操作方法上有很多相同之处。

cache缓存的配置文件在 config/cache.php 内,支持的驱动默认是 file
也就是文本文件存储。还有很多内置可选项:

  • file 文件存储
  • apc php内置缓存
  • array 内存变量
  • database 数据库
  • memcached / redis 内存数据库
  • dynamodb aws内存数据库

其中array驱动,是把数据直接存在变量内,放在服务器内存中,一次请求结束,或者php-fpm
闲置超时释放,就会注销掉。其他都提供了持久化的方案。

当然了,Cache缓存提供的数据类型就多了去了,根据驱动的不同,支持的存储结构也不相同。
比如文件类,只能是数组,链表,键值。而redis数据库则可以存储集合。这在使用的时候,
需要格外留意。

根据键名获取一个缓存值操作方法如下:

$users = Cache::get('users');

上面的代码使用了系统启动时注册的全局Cache门面方法,我们也可以从容器内获取一个Cache实例,
比如在路由内使用依赖注入的方式实例化:

Route::get('users', function (Illuminate\Contracts\Cache\Repository $cache) {
    return $cache->get('users');
});

laravel也为我们提供了极为便捷的助手函数 cache() 直接操作缓存。因为封装得过于精巧,
所以助手函数内定然是进行了大多数的情况判断。我们对源码稍作解析,以便明白其处理方法。

$arguments = func_get_args();

if (empty($arguments)) {
    return app('cache');
}

如果助手函数没有传入任何参数,比如这样:

$users = cache();

那就使用应用容器实例化一个 Cache::class 类。可以用于后续的链式方法调用。
接着看源码:

if (is_string($arguments[0])) {
    return app('cache')->get(...$arguments);
}

判断第一个位置参数,如果是字符串,那么推断用户就是要获取的键名。那就实例化Cache类并调用get方法获取缓存值。

if (! is_array($arguments[0])) {
    throw new Exception(
        'When setting a value in the cache, you must pass an array of key / value pairs.'
    );
}

为了排除其他所有情况,此处使用了NOT 逻辑判断。
也就是说,助手函数cache()除了接收字符串和数组,其他一概不处理。

接下来,如果传入的是数组,程序的处理方法:

return app('cache')->put(key($arguments[0]), reset($arguments[0]), $arguments[1] ?? null);

如果是数组,系统推断用户是要通过助手函数设置缓存值了。
那就就用第一个位置参数数组的键作为缓存的键名,数组的第一个值作为缓存的值。
同时查看是否有第二个位置参数,将其作为expired过期时间处理。没有的,则默认为null,永不过期。

$users = cache('key', 'default value');
$users = cache()->get('key', 'default value');

上面是根据键名获取缓存值。正好命中了源码中前两种情况。

$users = cache(['key' => 'value'], $minutes);
$users = cache()->put('key', 'value', $minutes);

写入数据也很简单,传入数组和过期时间,或者实例化之后直接调用put方法。

laravel日期时间处理默认使用Carbon类库,所以缓存也用到了该库,
并且把用法发挥到极致了。

比如我们可能想动态地设置过期时间,不计算时长,能不能设置为 到某个时间点结束
自然是可以的。这样来写代码:

cache()->put('key', 'value', Carbon::now()->addDay());

put方法第三个参数传入一个Carbon对象,就是默认缓存到指定的时间点。
至于时长,laravel帮你算好了。我们只关心这个到期时间点,代码可读性明显增强了许多。

其他方法不一一介绍了,特别说一下有个需求,比如说代码中,我们先查找缓存数据,如果没有就去程序上下文获取。
如果存在,就直接返回缓存数据。

这个逻辑用的很多,laravel提供了一个remember语法糖,让你解决这个操作步骤:

$users = cache()->remember('users', 120, function () {
    return User::all();
});

写在最后

本文通过对缓存助手函数cache()的分析,为大家介绍了Cache类传参的一些关键点。
特别是remember方法,在上下文逻辑不复杂的处理中,可有效减少代码量,非常直观。

Happy coding :-)

我是@程序员小助手,持续分享编程知识,欢迎关注。

相关文章
|
1月前
|
缓存 算法 Java
Caffeine Cache~高性能 Java 本地缓存之王
Caffeine Cache~高性能 Java 本地缓存之王
146 1
|
1月前
|
存储 缓存 Java
【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践
【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践
|
1月前
|
缓存 NoSQL Java
Spring Cache 缓存原理与 Redis 实践
Spring Cache 缓存原理与 Redis 实践
249 0
|
1月前
|
存储 缓存 NoSQL
把ruoyi-vue前后端分离项目的redis缓存改为本地缓存cache
把ruoyi-vue前后端分离项目的redis缓存改为本地缓存cache
246 0
|
1月前
|
XML 存储 缓存
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache管理器的实战开发指南(修正篇)
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache管理器的实战开发指南(修正篇)
44 0
|
1月前
|
存储 XML 缓存
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache功能的开发实战指南(一)
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache功能的开发实战指南
202 0
|
24天前
|
缓存 NoSQL Java
Spring Cache之本地缓存注解@Cacheable,@CachePut,@CacheEvict使用
SpringCache不支持灵活的缓存时间和集群,适合数据量小的单机服务或对一致性要求不高的场景。`@EnableCaching`启用缓存。`@Cacheable`用于缓存方法返回值,`value`指定缓存名称,`key`定义缓存键,可按SpEL编写,`unless`决定是否不缓存空值。当在类上使用时,类内所有方法都支持缓存。`@CachePut`每次执行方法后都会更新缓存,而`@CacheEvict`用于清除缓存,支持按键清除或全部清除。Spring Cache结合Redis可支持集群环境。
85 6
|
1月前
|
存储 缓存 监控
中间件Read-Through Cache(直读缓存)策略实现方式
【5月更文挑战第11天】中间件Read-Through Cache(直读缓存)策略实现方式
27 4
中间件Read-Through Cache(直读缓存)策略实现方式
|
1月前
|
存储 缓存 监控
中间件Read-Through Cache(直读缓存)策略注意事项
【5月更文挑战第11天】中间件Read-Through Cache(直读缓存)策略注意事项
21 2
|
1月前
|
存储 缓存 中间件
中间件Read-Through Cache(直读缓存)策略工作原理
【5月更文挑战第11天】中间件Read-Through Cache(直读缓存)策略工作原理
22 3