Laravel 5.5 + Redis。
在控制器中获得以下代码:
$products = Cache::remember('category_'.$category->alias.'_page_'.$page, 1440, function() use ($childrenCategoriesIndexes){
return Product::whereIn('category_id', $childrenCategoriesIndexes)
->userFilter()
->paginate(15);
});
它缓存每个页面。但是,如果有太多的自定义过滤器呢?这是来自scopeUserFilter()
模型的Product
:
public function scopeUserFilter($query) {
if (request('price_from')) {
$query->where('price', '>', request('price_from'));
}
if (request('price_to')) {
$query->where('price', '<', request('price_to'));
}
return $query;
}
而且只有2个变量。但是,如果有10个以上的变量,如何缓存这些数据怎么办?我认为像这样的钥匙不好:
'category_'.$category->alias.'_page_'.$page.'_'.request('price_from').'_'.request('price_to')
答案 0 :(得分:3)
将参数括起来,然后你可以尽可能多地包括:
$params = [
'page' => 1,
'price_from' => '',
'price_to' => '',
'param0' => '',
...
];
foreach (array_keys($params) as $param) {
if (request()->has($param))
$params[$param] = request()->input($param);
}
$prefix = 'category_';
$hashed = md5(json_encode($params));
$cache_key = $prefix . $hashed;
答案 1 :(得分:2)
代替:
...(我是从this article中学到的)一种替代方法,并且可能更灵活:
这意味着您的代码将如下所示:
$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;
});
答案 2 :(得分:1)
虽然@Ben的答案确实解决了我们如何缓存多个参数,但是缓存所有请求并不是一个好习惯。
缓存通常用于最常用的请求(高频率读取,不频繁写入)。例如,缓存前10个参数组合。如果你开始缓存长尾,你就会失去缓存的目的,因为你会更频繁地写入更频繁的写入和更少的读取。如果您使用内存缓存引擎,最终会耗尽内存
我建议您重新考虑一下您的缓存策略