php - Laravel 缓存与路由模型绑定?
问题描述
我正在向我的 Laravel 应用程序路由添加缓存。我有一个在我的网站上呈现博客文章的功能:
public function show(Post $post)
{
SEO::setTitle($post->title);
SEO::setDescription($post->subtitle);
SEO::setCanonical('https://employbl.com/blog/' . $post->slug);
SEO::opengraph()->setUrl('https://employbl.com/blog/' . $post->slug);
SEO::opengraph()->addProperty('type', 'article');
SEO::opengraph()->addImage($post->featured_image);
SEO::twitter()->setSite('@Employbl_Jobs');
$markdown = Markdown::parse($post->body);
return view('blog.post', compact('post', 'markdown'));
}
这是调用该方法的路由:Route::get('/blog/{post}', 'PostController@show')->name('posts.show');
以便我的博客呈现一个带有 slug 的 URL,例如:https ://employbl.com/blog/laravel-vue-tailwindcss-single-page-application-spa
在此路由上实现缓存以使用户更快地加载页面的最佳方法是什么?
会不会是这样的:
$post = Cache::rememberForever('blog-post' . $post->id, function(){
return $post;
});
或者路由模型绑定是否需要缓存?缓存键是否需要唯一,或者我可以只使用“博客文章”作为缓存键吗?$markdown
缓存变量而不是变量会更好$post
吗?两个都?
解决方案
你在这里有几个问题,所以我会尽力回答每个问题。答案可能不是完美的,因为我现在没有任何方式参考或确认自己的记忆。
如果您尝试缓存视图的最终输出,则可以有效地将最终视图调用替换为:
return Cache::rememberForever('blog-post' . $post->id, function() use ($post) {
// Do your SEO and markdown stuff here
return view('blog.post', compact('post', 'markdown'))->render();
});
缓存键对于帖子必须是唯一的。模型路由系统对缓存系统一无所知,它只是将值传递给控制器的一种方式,控制器根据 URI 对传入数据进行一些假设。所以你现在做的很好。
你的问题是我应该缓存帖子、降价还是两者兼而有之?是它可能不会有所作为
1)您正在调用模型 GET 路由。这具有每次从数据库加载 Post 的效果,使 Post 本身的缓存无关紧要。即使渲染视图本身的缓存也是如此。
2) 您的视图调用需要 Post 本身作为参数 [of compact() ]。您需要从某个地方加载它,这意味着再次调用数据库来检索帖子。
3)您正在使用Cache::rememberForever这意味着缓存永远不会过期。所以在第一次之后加载 Post 是没有意义的,因为它永远不会被再次使用(结果会被永久缓存!)。除非您使缓存无效(这使rememberForever变得毫无意义) ,否则未来的编辑(如果有的话)将不起作用。
因此,对于这种情况,我建议您远离模型路线,而是尝试使用传统的基于 id 的路线
public function show(Request $request, $id)
{
return Cache::remember('blog-post'.$id, ttl, function() use($id) {
$post = Post::find($id);
// Do SEO and markdown stuff
return view('blog.post', compact('post', 'markdown'))->render();
});
}
其中ttl是缓存过期的时间。
推荐阅读
- spring-cloud-feign - 在 RequestInterceptor 中伪装客户端名称
- excel - SharePoint 签入文件 - 未找到方法或数据成员
- python-3.x - 使用文本变量在标签中显示多行
- php - AJAX 表单数据未通过
- xamarin.android - 如何从蓝牙 LE (SIG) 十六进制值中提取重量值
- python - 为什么在定义全局名称时出现错误?
- node.js - Nodejs保存上传的文件
- jquery - 避免在点击外部时关闭下拉菜单
- java - Colors.xml:结尾部分不允许有内容
- authentication - 如何在asp.net核心的休息请求中发送jwt身份验证令牌