Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 具有路由模型绑定的Laravel缓存?_Php_Laravel_Laravel 5_Caching - Fatal编程技术网

Php 具有路由模型绑定的Laravel缓存?

Php 具有路由模型绑定的Laravel缓存?,php,laravel,laravel-5,caching,Php,Laravel,Laravel 5,Caching,我正在向我的Laravel应用程序路由添加缓存。我有一个在我的网站上呈现博客文章的功能: public function show(Post $post) { SEO::setTitle($post->title); SEO::setDescription($post->subtitle); SEO::setCanonical('https://employbl.com/blog/' . $post->slug);

我正在向我的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,如:

在该路由上实现缓存以便用户更快加载页面的最佳方法是什么

会不会是这样的:

$post = Cache::rememberForever('blog-post' . $post->id, function(){
     return $post;
});

或者缓存对于路由模型绑定是必要的吗?缓存密钥是否需要是唯一的,或者我可以只使用“blog 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();
});
对于post,缓存密钥需要是唯一的。模型路由系统对缓存系统一无所知,它只是一种将值传递给控制器的方法,控制器根据URI对传入数据进行一些假设。所以你现在做的很好

你的问题是,我应该缓存帖子,降价还是两者兼而有之?这可能不会有什么不同

1) 你在呼叫一个模型获取路径。这会导致每次从DB加载Post,从而使Post本身的缓存变得无关。即使使用渲染视图本身的缓存,情况也是如此

2) 视图调用需要Post本身作为[compact()]的参数。您需要从某个地方加载它,这意味着需要再次调用数据库来检索帖子

3) 您正在使用Cache::rememberForever,这意味着缓存永远不会过期。因此,在第一次之后加载帖子将毫无意义,因为它将永远不会被再次使用(结果将永远被缓存!)。除非使缓存失效(这使得MemberForever变得毫无意义),否则以后的编辑(如果有)将无法工作

因此,对于这种情况,我建议您远离模型路由,转而尝试传统的基于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是缓存过期的时间。

我想解决使用路由模型绑定的缓存模型的类似问题,并找到了以下解决方案

// On the Model class add the following method.

public function resolveRouteBinding($value, $field = null): ?Model
{
    return Cache::remember('my.custom.key'.$value, 3600, function () use ($value) {
        return $this->where('slug', $value)->firstOrFail();
    });
}
可在此处找到方法详细信息:

值得注意的是,您很可能希望在不使用
Cache::memory()
方法的情况下使用它,这样您就不会缓存返回null的内容。最好采用以下方法:

// On the Model class add the following method.

public function resolveRouteBinding($value, $field = null): ?Model
{
    $cacheName = "my.custom.key.{$value}";

    if (Cache::has($cacheName)) {
        return Cache::get($cacheName);
    }

    $result = $this->query('slug', $value)->firstOrFail();
    Cache::put($cacheName, $result, 3600);

    return $result;
}

根据要缓存的内容,如果静态内容是存储在
posts
表中的静态内容,则可能需要缓存整个页面内容。对于上述方法,缓存整个页面内容的最佳方法是什么?我无法告诉您,缓存db可以执行的最简单查询之一(通过主键检索记录)的性能会有多大的提高,但您也可以尝试缓存完整的html内容。我相信我曾经看到过这样一个包裹。基本上,它是一个中间件,缓存最终的
响应
,如果已经缓存,则立即返回。