缓存在 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()