如何使用laravel缓存优化索引方法?

如何使用laravel缓存优化索引方法?,laravel,caching,Laravel,Caching,有可能重构这个方法吗? 从数据库缓存数据的最佳实践是什么? 我应该在Controller、Repository或其他地方做吗 public function index(Request $request) { $requestData= trim($request->only(['keyword', 'tag', 'element'])); $requestData['type']= trim($request->input('type', 'items'));

有可能重构这个方法吗? 从数据库缓存数据的最佳实践是什么? 我应该在Controller、Repository或其他地方做吗

public function index(Request $request)
  {
    $requestData= trim($request->only(['keyword', 'tag', 'element']));
    $requestData['type']= trim($request->input('type', 'items'));
    $requestData['address'] = trim($request->input('street'.'house'.'corpus'));

    foreach ($requestData as $key => $value) {/* why use loop?*/
      if($key == 'keyword'){/* result without cache*/
         $requestData['field'] = trim($request->input('field', 'title'));
         $data= $this->model->byKeyword($type, $field, $keyword);
         $data['items']= $this->sort($data, $requestData);
      }
      else{
         $data['items'] = Cache::remember($requestData['type'].$key, 10080, function() use ($key, $value) {
        $method = 'by' . $key;
        $data = $this->model->$method($value)->orderBy('premium', 'desc'); 
                $this->sort($data, $requestData);
          });
      }
    }

    if(!$data['items']->first()) { 
      return back()
        ->withInput()
        ->with('status', 'Could not find anything try again!');
     }
    return $this->getView('index/index',$data);
}
排序方法:

public function Sort($data,$request)
{
    $requestData = $request->only(['limitBy', 'sortBy', 'offset', 'limit']);
    $requestData['type'] = $request->input('type', 'items');

//if $requestData == 'limitBy' 

    if($requestData['type'] == 'materials' ||  $requestData['type'] == 'groups')
    {
        $data->whereHas($requestData['type'] == 'groups' ? 'users' : 'user',function($query){
            $query->whereHas('addresses',function($subquery){
                $subquery->whereId( Auth::user()->addresses()->first()->id);
            });
        });
    }else{
        $data->ByExpireDate(
            [Carbon::now(),$requestData['limiBy'] == 'today_expire' ? Carbon::tomorrow() : Carbon::now()->addWeek(1)],
            $requestData['limiBy'] == 'today_expire' ? '1440' : '10080');
    }

//if $requestData == 'limit' 
    $data->where($requestData['limit'],'1');
//if $requestData == 'sortBy' 
    $data->orderBy($requestData['sortBy'],$requestData['direction'] );
//if $requestData == 'offset' 
    $data->skip($requestData['offset'])->take($requestData['limit']);
    return $data->count() > 1 ? $data->paginate(15) : $data->get();
}
我还没有完成这两种方法,因为我不知道如何重构它。 第一个方法返回数据,正如我前面所说的,而另一个方法对其进行排序

我认为修复getView方法并不重要,因为它只是检查现有文件并收集元数据:

public function getView($path,$data = null)
    {
        logger()->info(__METHOD__);
        if ( ! preg_match('/[^a-z\-_]+/', $path)) {  return 'wrong url';}//add Exception
        if ( ! view()->exists($path)) {              return 'wrong path view';}//add Exception

        $meta  = $this->getMeta($data);
        return view($path,compact('data','meta'));
    }
先谢谢你

有可能重构这个方法吗

对!!考虑以下两点:

  • 你能不能在6个月后再来看看这段代码,快速浏览并理解它在做什么,或者举个更好的例子。。。另一个看你的代码的开发人员可以浏览一下你的代码并了解到底发生了什么吗?如果答案是否定的,那么一定可以重构
  • 如果你需要大量的条件逻辑(即你的代码>如果 我对您的代码的一些即时观察结果如下:

    • 我不完全确定你想做什么
    • 为什么要抓取所有请求数据,然后执行一个巨大的
      if/else if
      block,其中只执行一个分支(我希望您理解这一点)为什么不设置一个循环呢
    • if/else if
      块周围的缩进很差,这使得它比以前更难理解(这可能是复制并粘贴到中,因此如果是这样的话,您可以忽略这一点)
    从数据库缓存数据的最佳实践是什么

    在Laravel,缓存从来没有真正发挥作用,但是考虑到有很多方法来完成相同的任务,每个任务都有自己的优势。您最好的方法应该是权衡您可用的不同选项,并选择最适合您的应用程序的选项。在文档中查看Laravel支持的不同选项:

    我应该在Controller、Repository或其他地方做吗

    同样,在Laravel中从未真正使用过缓存,但一般来说,如果您可以将其分离到自己的类中,并在需要时将其拉入,那么就这样做。考虑一下这里的单一责任原则,您的控制器或存储库是否负责缓存?如果没有,则尝试将其提取出来并将其拉入控制器中,或者在需要的任何地方

    编辑


    谢谢大家!!请你提供额外的帮助,告诉我你说的“只是建立一个循环”是什么意思?在上面的示例中,我尝试从存储库中读取数据并将结果转移到缓存中。我希望你理解我的观点或我的英语)提前谢谢你

    我们将一步一步地完成它,希望这能有所帮助

    public function index(Request $request)
    {
        logger()->info(__METHOD__);
        $keyword  = $request->input('keyword');
        $street   = $request->input('street');
        $house    = $request->input('house');
        $corpus   = $request->input('corpus');
        $tag      = $request->input('tag');
        $element  = $request->input('element');
        $field    = $request->input('field', 'title');
        $type     = $request->input('type', 'items');
    
    使用only()方法将8行合并为一行,更干净

    $requestData = $request->only(['keyword', 'street', 'house', 'corpus', 'tag', 'element', 'field', 'type']);
    
    您真的需要最后两个字段的默认值吗?如果是,您可以这样做:

    $requestData = $request->only(['keyword', 'street', 'house', 'corpus', 'tag', 'element']); // only get first 6
    $requestData['field'] = $request->input('field', 'title');
    $requestData['type'] = $request->input('type', 'items');
    
    我不知道你在这里做什么,因为你要用调用排序方法的return语句来结束这个方法 if语句中的其他分支都对缓存做了一些操作,我认为您在这里做错了什么

    if (isset($keyword)) {
        $data['items'] = $this->model->search($type, $field, $keyword)->orderBy('premium', 'desc');
        return $this->sort($data['items'], $request); // ending the method here!
    } 
    
    如果你看看其他的分支,你实际上在做同样的事情

  • 调用缓存记住
  • 在记住回调中:
  • 调用一个方法
  • 返回排序(为什么?)
  • 以下是每个分支的内部工作原理:

    $data['items'] = Cache::remember($type . $tag, 10080, function() use ($type, $tag, $request) {
        $data = $this->model->byTag($type, $tag)->orderBy('premium', 'desc');
        return $this->sort($data, $request);
    });
    $data['items'] = Cache::remember($type . $element, 10080, function() use ($type, $element, $request) {
        $data = $this->model->byElement($type, $element)->orderBy('premium', 'desc');
        return $this->sort($data, $request);
    });
    $data['items'] = Cache::remember($type . $street . $house . $corpus, 10080, function() use ($type, $street, $house, $corpus, $request) {
        $data = $this->model->byAddress($type, $street, $house, $corpus);
        return $this->sort($data, $request);
    });
    $data['items'] = Cache::remember($type, 10080, function() use ($type, $request) {
        $data = $this->model->byType($type)->orderBy('premium', 'desc');
        return $this->sort($data, $request);
    });
    
    因此,要抽象它,您需要这样看:

    $data['items'] = Cache::remember(/* keyForCache */, 10080, function() use (/* whatever we need to use */) {
        $data = $this->model->/* methodToCall */(/* request data value */)->orderBy('premium', 'desc');  // don't get what this method is doing at all! Sorry!
        return $this->sort($data, $requestData); // don't get what this method is doing at all! Sorry!
    });
    
    $requestData = [
        'keyword' => 'some value from request',
        'street'  => 'some value from request',
        'house'   => 'some value from request',
        'corpus'  => 'some value from request',
        'tag'     => 'some value from request',
        'element' => 'some value from request',
        'field'   => 'some value from request',
        'type'    => 'some value from request',
    ];
    
    $collection = collect($requestData);
    
    $collection->each(function ($value, $key) {
        Cache::remember($key, 10080, function() use ($key, $value) {
            $method = 'by' . $key;
            $data = $this->model->$method($value)->orderBy('premium', 'desc'); // shouldn't there be a first or get here?
            return $this->sort($data, $requestData); // don't get what this method is doing at all! Sorry!
        });
    });
    
    如果我是诚实的,你的代码对我来说仍然没有多大意义,所以我要让我的生活变得简单,让它变得通用 假设您的请求数据如下所示:

    $data['items'] = Cache::remember(/* keyForCache */, 10080, function() use (/* whatever we need to use */) {
        $data = $this->model->/* methodToCall */(/* request data value */)->orderBy('premium', 'desc');  // don't get what this method is doing at all! Sorry!
        return $this->sort($data, $requestData); // don't get what this method is doing at all! Sorry!
    });
    
    $requestData = [
        'keyword' => 'some value from request',
        'street'  => 'some value from request',
        'house'   => 'some value from request',
        'corpus'  => 'some value from request',
        'tag'     => 'some value from request',
        'element' => 'some value from request',
        'field'   => 'some value from request',
        'type'    => 'some value from request',
    ];
    
    $collection = collect($requestData);
    
    $collection->each(function ($value, $key) {
        Cache::remember($key, 10080, function() use ($key, $value) {
            $method = 'by' . $key;
            $data = $this->model->$method($value)->orderBy('premium', 'desc'); // shouldn't there be a first or get here?
            return $this->sort($data, $requestData); // don't get what this method is doing at all! Sorry!
        });
    });
    
    您可以遍历数组,然后将cache memory函数应用于数组的每个项

    foreach ($requestData as $key => $value) {
        Cache::remember($key, 10080, function() use ($key, $value) {
            $method = 'by' . $key;
            $data = $this->model->$method($value)->orderBy('premium', 'desc'); // shouldn't there be a first or get here?
            return $this->sort($data, $requestData); // don't get what this method is doing at all! Sorry!
        });
    }
    
    或者,您也可以在此处使用Laravel的收藏,如下所示:

    $data['items'] = Cache::remember(/* keyForCache */, 10080, function() use (/* whatever we need to use */) {
        $data = $this->model->/* methodToCall */(/* request data value */)->orderBy('premium', 'desc');  // don't get what this method is doing at all! Sorry!
        return $this->sort($data, $requestData); // don't get what this method is doing at all! Sorry!
    });
    
    $requestData = [
        'keyword' => 'some value from request',
        'street'  => 'some value from request',
        'house'   => 'some value from request',
        'corpus'  => 'some value from request',
        'tag'     => 'some value from request',
        'element' => 'some value from request',
        'field'   => 'some value from request',
        'type'    => 'some value from request',
    ];
    
    $collection = collect($requestData);
    
    $collection->each(function ($value, $key) {
        Cache::remember($key, 10080, function() use ($key, $value) {
            $method = 'by' . $key;
            $data = $this->model->$method($value)->orderBy('premium', 'desc'); // shouldn't there be a first or get here?
            return $this->sort($data, $requestData); // don't get what this method is doing at all! Sorry!
        });
    });
    
    格式很好

    if (!$items->first()) { // $items variable is never declated, what!?
        return back()
            ->withInput()
            ->with('status', 'Could not find anything try again!');
    }
    
    为什么要这样做

    return $this->getView('index/index', $data);
    
    你什么时候可以这么做

    return view('index/index', $data);
    
    也索引/索引-不是命名文件的好方法

    }
    
    更多提示:

  • 格式的一致性
  • 不要把整个if语句放在一行上
  • 当方法链接时,将其拆分为多行以使其更具可读性
  • 方法中使用空格分隔参数,例如:
  • 不要这样做:

    $this->function($a,$b,$c);
    
    $this->model->Search(...)
    
    这样做:

    $this->function($a, $b, $c);
    
    $this->model->search(...)
    
  • 如果方法是一个单词,则第一个字母不要使用大写字母,例如:
  • 不要这样做:

    $this->function($a,$b,$c);
    
    $this->model->Search(...)
    
    这样做:

    $this->function($a, $b, $c);
    
    $this->model->search(...)
    
    这不会阻止php快速处理它,但对可读性更好

  • 查看PSR-2编码标准,并尝试在代码中应用它们:
  • 编辑2

    排序方法 一行一行地通过这个

    • 名称方法以小写字母开头:
      sort()
      ,这是PHP中的常见做法
    • 在逗号和方法参数中的下一个参数之间留一个空格:
      ($data$request)

      公共函数排序($data,$request)
      {

    • 理想情况下,您应该传入请求数据,而不是依赖于方法来为您处理这些数据,考虑您的方法正在做多少不同的事情,以及它应该做多少不同的事情

      $requestData = $request->only(['limitBy', 'sortBy', 'offset', 'limit']);
      $requestData['type'] = $request->input('type', 'items');
      
    • 我不明白你在这里用你的代码做什么,抱歉

    • 这行代码不是:

      whereHas($requestData['type']='groups'?'users':'user'

    等同于
    whereHas(true/false…
    ,这是有效的代码吗?我很确定
    ($requestData['type']=='groups')
    将返回true或false

        if($requestData['type'] == 'materials' ||  $requestData['type'] == 'groups') {
            $data->whereHas($requestData['type'] == 'groups' ? 'users' : 'user', function ($query) {
                $query->whereHas('addresses', function($subquery) {
                    $subquery->whereId(Auth::user()->addresses()->first()->id);
                });
            });
        } else {
            $data->ByExpireDate(
                [Carbon::now(),$requestData['limiBy'] == 'today_expire' ? Carbon::tomorrow() : Carbon::now()->addWeek(1)],
                $requestData['limiBy'] == 'today_expire' ? '1440' : '10080');
        }
    
    • 对不起,我不明白剩下的部分,很困惑

      //如果$requestData=='限制' $data->where($requestData['limit'