Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.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_Caching - Fatal编程技术网

Php 在Laravel中使用用户过滤器缓存数据(不仅如此)

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)

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;
    }
公共函数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或缓存(用于计数)好的。如果你要缓存,使用增量