是否可以重构此方法? 从数据库缓存数据的最佳做法是什么? 我应该在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方法并不重要,因为它只检查现有文件并收集meta:
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'));
}
提前谢谢。
答案 0 :(得分:1)
是否可以重构此方法?
是的!请考虑以下两点:
if
块),那么考虑简化代码的可读性,你可以尝试将方法提取到方法中,或者如果你一遍又一遍地执行相同的检查把它扔进一个循环中。请查看以下链接:http://zaengle.com/blog/simplifying-conditional-expressions 我对您的代码的一些即时观察是:
if/else if
阻止,其中只有一个分支将被执行(我希望您理解这一点)为什么不要'你刚刚设置一个循环?if/else if
区块周围的缩进很差,这使得它比现在更难理解(可能会复制并粘贴到SO中,所以如果情况如此,你可以忽略这一点)从数据库缓存数据的最佳做法是什么?
从未真正使用Laravel中的缓存,但是考虑到有很多方法可以完成同样的工作,每个工作都有自己的优势。您最好的方法应该是衡量可用的不同选项,并选择最适合您应用的选项。在文档中查看Laravel支持的不同选项:https://laravel.com/docs/5.2/cache#configuration
我应该在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',
];
您可以遍历数组,然后将缓存记忆函数应用于数组的每个项目
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的集合:
$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);
索引/索引 - 不是命名文件的好方法!
}
进一步提示:
不要这样做:
$this->function($a,$b,$c);
这样做:
$this->function($a, $b, $c);
不要这样做:
$this->model->Search(...)
这样做:
$this->model->search(...)
这不会阻止PHP处理它AFAIK但它的可读性更好
修改2
排序方法 逐行贯穿......
sort()
,它在PHP中的常见做法在方法的参数中,在逗号和下一个参数之间留一个空格:($data, $request)
public function Sort($data,$request)
{
理想情况下,您可以传递请求数据,而不是依靠方法为您处理,请考虑您的方法正在做多少不同的事情以及应该多少< / strong>正在做。
$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 ==&#39;限制&#39; $ DATA-化合物其中($的RequestData [&#39;限制&#39],&#39; 1&#39); //如果$ requestData ==&#39; sortBy&#39; $ data-&gt; orderBy($ requestData [&#39; sortBy&#39;],$ requestData [&#39; direction&#39;]); //如果$ requestData ==&#39; offset&#39; $ DATA-&GT;跳过($的RequestData [&#39;偏移&#39;]) - &GT;取($的RequestData [&#39;限制&#39;]); 返回$ data-&gt; count()&gt; 1? $ data-&gt; paginate(15):$ data-&gt; get(); }
getView方法
我个人不会在这里做错误检查。如果它对你有意义,那很好!但是,Laravel允许您处理app/Exceptions/Handler.php
中的例外情况,请在此处的文档中详细了解它:https://laravel.com/docs/5.2/errors#the-exception-handler。
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'));
}
尝试打开一个新问题,看看是否有任何回复和进一步的帮助。