借助查询参数来利用 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 协议》,转载必须注明作者和本文链接
推荐文章: