缓存在 Laravel
Cache in Laravel
我是 Laravel 的初学者。在我的项目中,我使用存储库模式和 Laravel 7.
我有这个控制器:
class PageController extends Controller
{
protected $model;
/**
* PageController constructor.
* @param PageRepositoryInterface $repository
*/
public function __construct(PageRepositoryInterface $repository)
{
$this->model = $repository;
}
/**
* @param Request $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(Request $request)
{
if ($request->input('query') != "") {
$pages = $this->model->search($request->input('query'), 'id', 'asc', [], 30);
} else {
$pages = $this->model->listWithPaginate('id', 'desc', [], 30);
}
return view('admin.pages.list', ['pages' => $pages]);
}
/**
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function create()
{
return view('admin.pages.view');
}
/**
* @param PageRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function store(PageRequest $request)
{
if ($request->isMethod('post')) {
$data = [
'title' => $request->input('title'),
'description' => $request->input('description') ?? $request->input('title'),
'keywords' => $request->input('keywords') ?? $request->input('title'),
'content' => $request->input('content'),
'enable' => $request->input('enable') ?? 0,
'slug' => Str::slug($request->input('title'), '-')
];
$this->model->create($data);
return redirect()->route('page.index')->with('success', __('messages.record_save_info'));
}
}
/**
* @param int $id
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function edit(int $id)
{
Cache::forget("page.{$id}");
return view('admin.pages.view', ['page' => $this->model->findOrFail($id)]);
}
/**
* @param PageRequest $request
* @param int $id
* @return \Illuminate\Http\RedirectResponse
*/
public function update(PageRequest $request, int $id)
{
if ($request->isMethod('put')) {
$data = [
'title' => $request->input('title'),
'description' => $request->input('description'),
'keywords' => $request->input('keywords'),
'content' => $request->input('content'),
'enable' => $request->input('enable') ?? 0,
'slug' => Str::slug($request->input('title'), '-')
];
$this->model->update($data, $id, 'id');
return redirect()->route('page.index')->with('success', __('messages.record_edit_info'));
}
}
/**
* @param Request $request
* @param int $id
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(Request $request, int $id)
{
if ($request->isMethod('delete')) {
$this->model->delete($id);
return redirect()->route('page.index')->with('success', __('messages.record_remove_info'));
}
}
}
和 CachingBaseRepository
abstract class CachingBaseRepository implements RepositoryInterface
{
use ScopeActiveTrait;
protected $model;
protected $cacheKey;
protected $cacheTime;
public function all()
{
return Cache::remember($this->cacheKey.'.all', $this->cacheTime, function () {
return $this->model->get();
});
}
public function allEnables()
{
return Cache::remember($this->cacheKey.'.enables', $this->cacheTime, function () {
return $this->model->active()->get();
});
}
public function list(string $orderByColumn, string $orderBy = 'desc', array $with = [])
{
return Cache::remember($this->cacheKey.'.list', $this->cacheTime, function () use($with, $orderByColumn, $orderBy) {
return $this->model->with($with)
->orderBy($orderByColumn, $orderBy)
->get();
});
}
public function listWithPaginate(string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 10)
{
return Cache::remember($this->cacheKey.'.listWithPaginate', $this->cacheTime, function () use($with, $orderByColumn, $orderBy, $perPage) {
return $this->model->with($with)
->orderBy($orderByColumn, $orderBy)
->paginate($perPage)->appends(request()->query());
});
}
public function create(array $data): int
{
Cache::forget($this->cacheKey);
Cache::forget($this->cacheKey.'.all');
Cache::forget($this->cacheKey.'.enables');
Cache::forget($this->cacheKey.'.list');
Cache::forget($this->cacheKey.'.listWithPaginate');
return $this->model->create($data)->id;
}
public function update(array $data, int $id, string $attribute = 'id'): void
{
$this->model->where($attribute, '=', $id)->update($data);
Cache::forget($this->cacheKey);
Cache::forget($this->cacheKey.".{$id}");
Cache::forget($this->cacheKey.'.all');
Cache::forget($this->cacheKey.'.enables');
Cache::forget($this->cacheKey.'.list');
Cache::forget($this->cacheKey.'.listWithPaginate');
}
public function delete(int $id): void
{
$this->model->destroy($id);
Cache::forget($this->cacheKey);
Cache::forget($this->cacheKey.'.all');
Cache::forget($this->cacheKey.'.enables');
Cache::forget($this->cacheKey.'.list');
Cache::forget($this->cacheKey.'.listWithPaginate');
}
public function find(int $id)
{
return Cache::remember($this->cacheKey.".{$id}", $this->cacheTime, function () use ($id) {
return $this->model->find($id);
});
}
public function getModel()
{
return Cache::remember($this->cacheKey.".all", $this->cacheTime, function (){
return $this->model;
});
}
public function findOrFail(int $id)
{
return Cache::remember($this->cacheKey.".{$id}", $this->cacheTime, function () use ($id) {
return $this->model->findOrFail($id);
});
}
}
我有分页问题。当我转到第 2、3、7 或 10 页时 - 我总是看到与第 1 页相同的内容。
我的代码是最优的吗?是否可以替换重复 - 一个功能(我在控制器中删除了 - 在编辑中):
:: Cache forget ($ this-> cacheKey);
:: Cache forget ($ this-> cacheKey.. 'All');
:: Cache forget ($ this-> cacheKey. '. Enables');
:: Cache forget ($ this-> cacheKey.. 'Letter');
:: Cache forget ($ this-> cacheKey. '. ListWithPaginate');
某个功能?
那是因为当你调用第一页时它被缓存,在第二页因为键没有改变缓存假设你想要缓存版本和 returns 第 1 页。
一种方法是根据输入更新标签:
public function listWithPaginate(string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 10)
{
$tag = sprintf('%s.listWithPaginate.%s.%s',
$this->cacheKey,
serialize(func_get_args()),
serialize(request()->query())
);
return Cache::remember($tag, $this->cacheTime...;
}
另一种方法是缓存所有行,然后从缓存中对它们进行分页。您将需要制作自定义集合分页器(google "laravel 集合分页器,并且会找到很多教程)。您可能仍然需要将 $with 添加到缓存标签中。对于许多结果来说,不是好主意。
不要尝试缓存所有内容。缓存并不总是最快的方法。最好尝试优化您的数据库。
我个人认为在存储库中缓存不是一个好主意。
要刷新多个标签,您可以使用:
Cache::tags('tag1', 'tag2')->flush()
我是 Laravel 的初学者。在我的项目中,我使用存储库模式和 Laravel 7.
我有这个控制器:
class PageController extends Controller
{
protected $model;
/**
* PageController constructor.
* @param PageRepositoryInterface $repository
*/
public function __construct(PageRepositoryInterface $repository)
{
$this->model = $repository;
}
/**
* @param Request $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(Request $request)
{
if ($request->input('query') != "") {
$pages = $this->model->search($request->input('query'), 'id', 'asc', [], 30);
} else {
$pages = $this->model->listWithPaginate('id', 'desc', [], 30);
}
return view('admin.pages.list', ['pages' => $pages]);
}
/**
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function create()
{
return view('admin.pages.view');
}
/**
* @param PageRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function store(PageRequest $request)
{
if ($request->isMethod('post')) {
$data = [
'title' => $request->input('title'),
'description' => $request->input('description') ?? $request->input('title'),
'keywords' => $request->input('keywords') ?? $request->input('title'),
'content' => $request->input('content'),
'enable' => $request->input('enable') ?? 0,
'slug' => Str::slug($request->input('title'), '-')
];
$this->model->create($data);
return redirect()->route('page.index')->with('success', __('messages.record_save_info'));
}
}
/**
* @param int $id
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function edit(int $id)
{
Cache::forget("page.{$id}");
return view('admin.pages.view', ['page' => $this->model->findOrFail($id)]);
}
/**
* @param PageRequest $request
* @param int $id
* @return \Illuminate\Http\RedirectResponse
*/
public function update(PageRequest $request, int $id)
{
if ($request->isMethod('put')) {
$data = [
'title' => $request->input('title'),
'description' => $request->input('description'),
'keywords' => $request->input('keywords'),
'content' => $request->input('content'),
'enable' => $request->input('enable') ?? 0,
'slug' => Str::slug($request->input('title'), '-')
];
$this->model->update($data, $id, 'id');
return redirect()->route('page.index')->with('success', __('messages.record_edit_info'));
}
}
/**
* @param Request $request
* @param int $id
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(Request $request, int $id)
{
if ($request->isMethod('delete')) {
$this->model->delete($id);
return redirect()->route('page.index')->with('success', __('messages.record_remove_info'));
}
}
}
和 CachingBaseRepository
abstract class CachingBaseRepository implements RepositoryInterface
{
use ScopeActiveTrait;
protected $model;
protected $cacheKey;
protected $cacheTime;
public function all()
{
return Cache::remember($this->cacheKey.'.all', $this->cacheTime, function () {
return $this->model->get();
});
}
public function allEnables()
{
return Cache::remember($this->cacheKey.'.enables', $this->cacheTime, function () {
return $this->model->active()->get();
});
}
public function list(string $orderByColumn, string $orderBy = 'desc', array $with = [])
{
return Cache::remember($this->cacheKey.'.list', $this->cacheTime, function () use($with, $orderByColumn, $orderBy) {
return $this->model->with($with)
->orderBy($orderByColumn, $orderBy)
->get();
});
}
public function listWithPaginate(string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 10)
{
return Cache::remember($this->cacheKey.'.listWithPaginate', $this->cacheTime, function () use($with, $orderByColumn, $orderBy, $perPage) {
return $this->model->with($with)
->orderBy($orderByColumn, $orderBy)
->paginate($perPage)->appends(request()->query());
});
}
public function create(array $data): int
{
Cache::forget($this->cacheKey);
Cache::forget($this->cacheKey.'.all');
Cache::forget($this->cacheKey.'.enables');
Cache::forget($this->cacheKey.'.list');
Cache::forget($this->cacheKey.'.listWithPaginate');
return $this->model->create($data)->id;
}
public function update(array $data, int $id, string $attribute = 'id'): void
{
$this->model->where($attribute, '=', $id)->update($data);
Cache::forget($this->cacheKey);
Cache::forget($this->cacheKey.".{$id}");
Cache::forget($this->cacheKey.'.all');
Cache::forget($this->cacheKey.'.enables');
Cache::forget($this->cacheKey.'.list');
Cache::forget($this->cacheKey.'.listWithPaginate');
}
public function delete(int $id): void
{
$this->model->destroy($id);
Cache::forget($this->cacheKey);
Cache::forget($this->cacheKey.'.all');
Cache::forget($this->cacheKey.'.enables');
Cache::forget($this->cacheKey.'.list');
Cache::forget($this->cacheKey.'.listWithPaginate');
}
public function find(int $id)
{
return Cache::remember($this->cacheKey.".{$id}", $this->cacheTime, function () use ($id) {
return $this->model->find($id);
});
}
public function getModel()
{
return Cache::remember($this->cacheKey.".all", $this->cacheTime, function (){
return $this->model;
});
}
public function findOrFail(int $id)
{
return Cache::remember($this->cacheKey.".{$id}", $this->cacheTime, function () use ($id) {
return $this->model->findOrFail($id);
});
}
}
我有分页问题。当我转到第 2、3、7 或 10 页时 - 我总是看到与第 1 页相同的内容。
我的代码是最优的吗?是否可以替换重复 - 一个功能(我在控制器中删除了 - 在编辑中):
:: Cache forget ($ this-> cacheKey);
:: Cache forget ($ this-> cacheKey.. 'All');
:: Cache forget ($ this-> cacheKey. '. Enables');
:: Cache forget ($ this-> cacheKey.. 'Letter');
:: Cache forget ($ this-> cacheKey. '. ListWithPaginate');
某个功能?
那是因为当你调用第一页时它被缓存,在第二页因为键没有改变缓存假设你想要缓存版本和 returns 第 1 页。
一种方法是根据输入更新标签:
public function listWithPaginate(string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 10)
{
$tag = sprintf('%s.listWithPaginate.%s.%s',
$this->cacheKey,
serialize(func_get_args()),
serialize(request()->query())
);
return Cache::remember($tag, $this->cacheTime...;
}
另一种方法是缓存所有行,然后从缓存中对它们进行分页。您将需要制作自定义集合分页器(google "laravel 集合分页器,并且会找到很多教程)。您可能仍然需要将 $with 添加到缓存标签中。对于许多结果来说,不是好主意。
不要尝试缓存所有内容。缓存并不总是最快的方法。最好尝试优化您的数据库。
我个人认为在存储库中缓存不是一个好主意。
要刷新多个标签,您可以使用:
Cache::tags('tag1', 'tag2')->flush()