Laravel: 如何缓存路由5分钟?

5

我希望在Laravel项目中缓存一个路由,并且每5分钟清除一次。

我查了很多文章,但只找到了artisan route:cache命令,而不知道是否可以配置缓存时间。

这是我的路由routes/web.php

$router->group(['middleware' => ['api','cors']], function () use ($router) {
    $router->get('game', ['uses' => 'GameController@checkGameStatus']);
    $router->get('promo', ['uses' => 'PromoController@sendPromoCode']);
    $router->get('get_leaders', ['uses' => 'GameController@getLeaders']); // <-- cache this for 5m
});

每当用户加载评分页面时,getLeaders()函数都会启动DB请求以获取和计算所有用户结果。因此,我希望减少DB负载,并使其每5分钟计算一次所有结果。其余时间,get_leaders路由应仅发送缓存的json输出。
如何设置这样的配置?是否可以只使用Laravel(artisan)完成,还是应该更改.htaccess文件(我正在使用apache)?

1
路由缓存并不是你在这里寻找的,路由缓存只是缓存传入请求到控制器操作的翻译,而不是来自控制器的实际数据或响应。要实现这种缓存,请在控制器操作中使用普通缓存门面 https://laravel.com/docs/5.8/cache#storing-items-in-the-cache - Alec Joy
你可能不想要路由缓存,而是对象/结果缓存。https://laravel.com/docs/master/cache - brombeer
3个回答

6

为了补充@TimLewis的回答,如果您使用的是Laravel 5.8或更新版本,则Cache::remember函数可以大大简化控制器代码。

public function getLeaders(){
  $leaders = Cache::remember('leaders', 300, function () {
    return Leader::where(...)->get();
  });
  return response()->json(['leaders' => $leaders]);
}

Cache::remember函数负责整个缓存工作流程,首先检查缓存中是否存在leaders对象,如果存在,则返回。如果没有,则在闭包内运行代码,并将结果存储在缓存中,使用第一个参数指定的键,在第二个参数指定的秒数内进行缓存。因此,在这种情况下,它将在键“leaders”下缓存结果300秒(5分钟)。


是的,这绝对是一个更紧凑和简洁的答案;将检查逻辑应用于包装函数也非常酷,我得使用一下 :) 唯一的问题是,300 是缓存时间吗?这个答案说“5分钟”,所以我认为那有点长了。 - Tim Lewis
1
在5.8及更高版本中,缓存门面被改为符合PSR-7标准,现在它需要的是秒数而不是分钟数。因此,在这种情况下,300秒等于5分钟。 - Alec Joy
啊,明白了。那很有道理! - Tim Lewis
抱歉,我的版本低于5.8呢。不过还是谢谢你的回答! - mr.boris

6

其实这是一个非常简单的问题。在你的函数getLeaders()中,你需要修改以下代码:

public function getLeaders(){
  $leadersCache = Cache::get("leaders", null);
  if($leadersCache){
    return response()->json(["leaders", $leadersCache], 200);
  }

  $leaders = Leader::where(...)->get();
  Cache::put("leaders", $leaders, 5);

  return response(["leaders", $leaders], 200);
}

所以,这个代码首先会检查缓存中是否存在“leaders”。如果存在,它将直接返回该值。如果不存在(当第一次调用此路由时),则会计算结果并使用Cache::put()将其存储在缓存中,然后返回结果。在接下来的5分钟内,每次访问该路由时,它都会返回缓存的结果,直到重新开始该进程。
请注意,上面的代码是伪代码,因为您的控制器未显示,但该方法可以轻松适应现有代码。此外,您可能需要在控制器顶部包含use Cache;或通过\Cache::{method}引用Cache。
关于缓存的所有内容都可以在文档中找到:https://laravel.com/docs/5.7/cache

稍微修改一下,因为您可以使用cache::remember函数来简化这个过程。 - Alec Joy
@AlecJoy 感谢您的编辑建议,但它与我编写的代码有很大的偏差。您可以将其作为自己的答案编写(我不知道 remember 方法的存在,但肯定是一个不错的方法)。 - Tim Lewis
好的,我会这样做。 - Alec Joy
1
谢谢!Laravel太棒了 :) - mr.boris

0

Laravel > 7 可以使用 cash::rmember(),这样可以节省很多时间而减少代码量。 例子:

$getleaders = Cache::remember('getleaders', 'minutes', function () {
 u query;
  });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接