Php 在Laravel中使用用户过滤器缓存数据(不仅如此)
Laravel 5.5+Redis 在控制器中获取了以下代码:Php 在Laravel中使用用户过滤器缓存数据(不仅如此),php,laravel,caching,Php,Laravel,Caching,Laravel 5.5+Redis 在控制器中获取了以下代码: $products = Cache::remember('category_'.$category->alias.'_page_'.$page, 1440, function() use ($childrenCategoriesIndexes){ return Product::whereIn('category_id', $childrenCategoriesIndexes)
$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;
}
公共函数scopeUserFilter($query){
如果(请求(“价格来源”)){
$query->where('price','>',request('price_from');
}
如果(请求(‘价格)’){
$query->where('price','alias.''U page'.''.'page'.'''.'''.'''.'''.'请求('price'U from').'.'''.'请求('price'U to')
对参数进行哈希运算,然后您可以包括尽可能多的参数:
$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;
散列参数,然后可以包括尽可能多的参数:
$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;
虽然@Ben的答案确实说明了如何缓存多个参数,但缓存所有请求并不是一个好的做法 缓存通常用于最常见的请求(高频率读取、不频繁写入)。例如,缓存前10个参数组合。如果您开始缓存长尾,您将无法达到缓存的目的,因为您将倾向于更频繁的写入和更少的读取。如果使用内存缓存引擎,最终您将耗尽内存
我建议重新考虑您的缓存策略虽然@Ben的回答确实提到了如何缓存多个参数,但缓存所有请求并不是一个好的做法 缓存通常用于最常见的请求(高频率读取、不频繁写入)。例如,缓存前10个参数组合。如果您开始缓存长尾,您将无法达到缓存的目的,因为您将倾向于更频繁的写入和更少的读取。如果使用内存缓存引擎,最终您将耗尽内存 我建议您重新考虑缓存策略,而不是:
- 定义所有可能参数的数组
- 循环遍历该数组以检查请求是否包含任何这些参数,如果包含,则将该值分配给数组中的相关键
- 创建数组哈希以用作缓存的键
- 创建一个包含所有请求参数的数组,并按字母顺序对它们进行排序
- 使用此排序数组重新生成url
- 创建此url的哈希以用作缓存的密钥
$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;
});
而不是:
- 定义所有可能参数的数组
- 循环遍历该数组以检查请求是否包含任何这些参数,如果包含,则将该值分配给数组中的相关键
- 创建数组哈希以用作缓存的键
- 创建一个包含所有请求参数的数组,并按字母顺序对它们进行排序
- 使用此排序数组重新生成url
- 创建此url的哈希以用作缓存的密钥
$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;
});
这是一个非常好的解决方案,谢谢!1个问题:在这种情况下,如何为任何request()参数设置默认值?我使用了以下方法:
$page=request()->input('page','1');
使用参数键及其默认值创建数组,并检查是否存在输入。执行此操作:$input=request()->仅([['page','1'],'price_from','price_to']);
但是$input
数组中没有页面
变量(使用dd($input)
进行检查)这是一个非常好的解决方案,谢谢!1个问题:在这种情况下,如何将默认值设置为任何request()参数?我使用了这个:$page=request()->input('page','1'))
使用参数键及其默认值创建数组,并根据请求检查是否存在输入。执行此操作:$input=request()->仅([['page','1'],'price\u from','price\u to']);
但$input
数组中没有页面
变量(使用dd($input)
进行检查)没错。如何正确计算最流行的查询?这取决于查询的数量和种类。对于大流量,可以使用Hadoop mapreduce解析Nginx/Apache请求日志。对于中等流量,可以使用DB或缓存(用于计数)很好。如果您要缓存,请使用递增。您是对的。如何正确计算最流行的查询?这取决于查询的数量和种类。对于巨大的流量,您可以使用Hadoop mapreduce解析Nginx/Apache请求日志。对于中等流量,请使用DB或缓存(用于计数)好的。如果你要缓存,使用增量