借助查询参数来利用 Laravel 缓存

  Laravel 提供了非常直观和有效的方法来缓存你的项目的响应,不论你的项目是什么(Restful API , web 端或者其他),通常来说,Laravel 可以存储任何你发送的(HTML,JSON,集合,Eloquent 实例和其他简单的)对应你提供的到期时间到缓存系统。

  直接使用代码,缓存一个简单的响应片段可以是这样

    return Cache::remember($rememberKey, $minutes , function() use ($data) {
       return $data;
    });

  实际来说也是代码看上去的这么简单,你可以调用记住标记以获取缓存数据,并且可以当它不存在的时候进行缓存,发送 $rememberKey 来标识缓存系统中的数据及过期时间(以分钟为单位)。使用闭包,您可以将数据返回以存储在缓存系统中。他如此简单以至于开发人员可能不理解一条线上实现所有功能,我们来一步步理清这里最相关的元素。

  这里存在几种使用缓存的方法,如 PUT, PULL, GET等,(这里 有所有方法的详细),但 remember 方法是你需要的,因为她为你存储和检索数据。

  这里的问题是“ Laravel 如何确定何时存储数据?”

  为了回答这个问题,我们需要使用关注另一个基本元素“ rememberKey ”,根据 $rememberKey 的值, Laravel 会知道这个数据是否已被缓存。所以这里是这个值的重要性,因为如果你使用相同的 $rememberKey 缓存所有的响应,你将在到期时间获得相同的响应,看上去很明显不可以这样不可以?

  不幸的是,对于其他场景来说这不是很明显。您知道 $rememberKey 的唯一值的重要性,您决定使用当前的 URL ,因此代码如下所示:

    $url = request()->url();
    return Cache::remember($url, $minutes, function () use ($data) {
       return $data;
    });

  几乎相同,但现在 $rememberKey 是当前请求的 URL,这样你就可以确定记住的密钥依据请求而有所不同。

  例如,如果您收到请求到此 yourdomain.com/products URL,将使用该确切值来缓存响应。每当用户转到另一个 URL 时yourdomain.com/categories ,您需要确保缓存系统将返回相应的值并相应存储。

  但是,等一下!我们假设您正在使用查询参数对结果进行排序或分页,因此您的网址如下所示:yourdomain.com/products?page=2&sort_by=price 。在这种情况下,当您获取 URL 时,$url = request()->url() 它不会获取查询参数,这意味着由查询参数引入的响应中的更改不会被反映出来。

  没问题,你只需要包含查询参数,一切都会很好,对吧?我们开始做吧。

    $fullUrl = request()->fullUrl();
    return Cache::remember($fullUrl, $minutes, function () use ($data) {
        return $data;
    });

  好的,已经完成了!或不?一点点耐心的我们来做一些测试。如果用户发送请求,yourdomain.com/products?page=2&sort_by=price 它将缓存数据并返回响应。如果用户发送请求 yourdomain.com/products?page=1&sort_by=name ,它将再次缓存数据并返回。漂亮!它缓存不同的响应并返回它们。现在,最后一次测试。用户访问 yourdomain.com/products?page=2&sort_by=price 然后访问 yourdomain.com/products?sort_by=price&page=2 。这是一个不同的请求,所以缓存系统将独立缓存一切,很好!哦,等一下!这是同样的回应。查询字符串中的顺序并不重要,您的项目将返回相同的响应,如果缓存系统应该存储相同的响应,但是它不会返回相同的响应。

  哦,我现在该怎么办?看起来解决方案并不像我们开始时那么简单。我们需要一种确定方式,独立于查询字符串的顺序,只要它们相同,我们不想再次缓存数据。我们需要对查询字符串进行排序。

我们来写代码:

    $url = request()->url();
    $queryParams = request()->query();

    //Sorting query params by key (acts by reference)
    ksort($queryParams);

    //Transforming the query array to query string
    $queryString = http_build_query($queryParams);

    $fullUrl = "{$url}?{$queryString}";

    return Cache::remember($fullUrl, $minutes, function () use ($data) {
        return $data;
    });

  这里的魔法在哪里?那么我们只需使用查询方法在关联数组中获取查询参数,然后使用key(而不是值),使用ksort进行排序。ksort 函数作为参考,所以我们不需要再次分配。然后使用查询参数排序,我们可以再次构建查询字符串,使用http_build_query最终以正确的方式构建 fullUrl ,将其用作要记住的键。

  在之后,如果用户访问 yourdomain.com/products?sort_by=price&page=2 它将与 yourdomain.com/products?page=2&sort_by=price 允许您缓存相同响应相同,即使请求中的URL看起来有所不同。

如果你想要一个“花哨”的解决方案,你甚至可以哈希fullUrl,就像这样:

    $url = request()->url();
    $queryParams = request()->query();

    ksort($queryParams);

    $queryString = http_build_query($queryParams);

    $fullUrl = "{$url}?{$queryString}";

    $rememberKey = sha1($fullUrl);

    return Cache::remember($rememberKey, $minutes, function () use ($data) {
        return $data;
    });

翻译自:https://laravel-news.com/cache-query-param...

本作品采用《CC 协议》,转载必须注明作者和本文链接
Keep Young, Keep Simple.
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!