Я действительно не понимаю, почему ваш код не работает.Единственными потенциальными проблемами, которые я вижу, являются ключи кеша, которые могут содержать проблемные символы, а также способ проверки кэшированного значения.Поскольку вы используете Cache::has($key)
до Cache::get($key)
, вы можете получить состояние гонки, при котором первый вызов возвращает true
, а последний null
, поскольку значение в кэше истекло сразу между двумя вызовами.
Я попытался решить обе проблемы в следующем фрагменте:
public function search($filter, $query, $layout, Request $request)
{
if($layout == "list-map") {
return view("list-map")->with(['filter' => $filter, 'query' => $query, 'layout' => 'list-map']);
} else {
$offsetPages = $request->input('page', 1) - 1;
$cacheKey = md5("{$filter}_{$query}_{$offsetPages}");
$duration = 5; // todo: make this configurable or a constant
[$totalCount, $results] = Cache::remember($cacheKey, $duration, function () use ($filter, $query) {
$results = $this->getResults($filter, $query);
$totalCount = $results->count();
$filteredResults = $results->slice($offsetPages, $this->resultsPerPage);
return [$totalCount, $filteredResults];
});
$results = new LengthAwarePaginator($results,
$totalCount,
$this->resultsPerPage,
$request->input('page', 1),
['path' => LengthAwarePaginator::resolveCurrentPath()]
);
return view($layout)->with(compact('filter', 'query', 'layout', 'results'));
}
}
Встроенная функция Cache::remember()
не использует Cache::has()
под капотом.Вместо этого он просто позвонит Cache::get()
.Поскольку эта функция будет возвращать null
по умолчанию, если кэш не был задействован, функция может легко определить, должно ли оно выполнить закрытие или нет.
Я также обернул $cacheKey
в md5()
, чтодает последовательно действительный ключ.
Глядя на следующую часть вашего кода
$results = $this->getResults($filter, $query);
$totalCount = $results->count();
$filteredResults = $results->slice($offsetPages, $this->resultsPerPage);
Я вполне уверен, что весь поиск мог бы быть улучшен (независимо от кэширования).Потому что кажется, что вы загружаете все результаты для определенного поиска в память, даже если вы выбрасываете большинство его частей.Конечно, есть лучший способ сделать это.