Rumah > Soal Jawab > teks badan
Saya menggunakan repositori dalam projek untuk cache semua pertanyaan.
Terdapat BaseRepository.
use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Cache; class BaseRepository implements BaseRepositoryInterface{ protected $model; protected int $cacheDuration = 600; //per seconds public function __construct(Model $model) { return $this->model = $model; } public function paginate(int $paginate,string $cacheKey) { return Cache::remember($cacheKey,$this->cacheDuration , function () use ($paginate) { return $this->model->latest()->paginate($paginate); }); } // other methods ... }
Kemudian saya menggunakan repositori ini dalam perkhidmatan saya
Perkhidmatan Pos:
use Illuminate\Support\Facades\App; class PostService{ public PostRepositoryInterface $postRepository; public function __construct() { $this->postRepository = App::make(PostRepositoryInterface::class); } public function paginate(int $paginate, string $cacheKey) { return $this->postRepository->paginate($paginate,$cacheKey); } }
Akhirnya saya menggunakan PostService dalam pengawal
Pengawal belakang:
class PostController extends Controller{ public PostService $postService; public function __construct() { $this->postService = App::make(PostService::class); } public function index() { string $cacheKey = "posts.paginate"; return $this->postService->paginate(10); } }
kaedah indeks akan mengembalikan 10 rekod terbaharu pertama dengan betul. Sekarang saya perlu mencipta CacheKey yang unik untuk semua pertanyaan repositori. Contohnya
TableName concat FunctionName // posts.paginate
Jadi saya boleh menggunakan kod ini dalam semua kaedah repositori
public function paginate(int $paginate) { $cacheKey = $this->model->getTable().__FUNCTION__; return Cache::remember($cacheKey,$this->cacheDuration , function () use ($paginate) { return $this->model->latest()->paginate($paginate); }); }
Ini bagus. Tetapi masalahnya ialah kod ini diulang dalam semua kaedah kelas. Jika saya menggunakan kod ini dalam kelas lain, nama kaedah akan menjadi salah. Adakah anda mempunyai sebarang cadangan untuk mengelakkan pertindihan kod ini?
P粉4019012662024-03-20 15:30:59
Saya menyelesaikan masalah ini dengan menghantar nama fungsi ke kelas lain
Saya mencipta kelas CacheKey:
class CacheKey{ public static function generate(Model $model, $functionName):string { return $model->getTable()."_".$functionName; } }
Kemudian dalam mana-mana kaedah repositori kita boleh menggunakan kelas pembantu ini seperti ini:
$cacheKey = CacheKey::generate($this->model,__FUNCTION__);
P粉2877263082024-03-20 15:11:01
Anda boleh menggunakan kaedah ajaib dengan cara ini:
class CacheService { private const $cacheableMethods = ['paginate']; private $otherSerivce; public __construct($otherSerivce) { $this->otherSerivce = $otherSerivce; } public __get($method, $args) { if(!in_array($method, static::$cachableMethods)) { return $this->otherSerivce->{$method}(...$args); } return Cache::remember(implode([$method, ...$args], ':'), function () { return $this->otherSerivce->{$method}(...$args); }); } }