1. Go to this page and download the library: Download studocu/cacheable-entities library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
studocu / cacheable-entities example snippets
class RecommendedBooksQuery implements Cacheable, SerializableCacheable
{
public function getCacheTTL(): int
{
return 3600 * 24;
}
public function getCacheKey(): string
{
return "books:popular.v1";
}
public function get(): Collection
{
return Book::query()
->wherePopular()
->orderByDesc('document_popularity_scores.score')
->take(config('popular.books.limit'))
->get();
}
public function serialize(mixed $value): array
{
return $value->pluck('id')->all();
}
public function unserialize(mixed $value): Collection
{
return Book::query()->findMany($value);
}
}
$query = new RecommendedBooksQuery();
// Get a non-blocking cache result in the web endpoint.
resolve(AsyncCache::class)->get($query);
// Get a blocking cache result in the API endpoint.
resolve(SyncCache::class)->get($query);
// Get real time value
$query->get();
use Author;
use Book;
use Illuminate\Database\Eloquent\Collection;
use StuDocu\CacheableEntities\Contracts\Cacheable;
use StuDocu\CacheableEntities\Contracts\SerializableCacheable;
class AuthorPopularBooksQuery implements Cacheable
{
public const DEFAULT_LIMIT = 8;
public function __construct(
protected readonly Author $author,
protected readonly int $limit = self::DEFAULT_LIMIT,
) {
}
public function getCacheTTL(): int
{
return 3600 * 24;
}
public function getCacheKey(): string
{
return "authors:{$this->author->id}:books:popular.v1";
}
public function get(): Collection
{
return Book::query()
->join('book_popularity_scores', 'book_popularity_scores.book_id', '=', 'books.id')
->where('author_id', $this->author->id)
->whereValid()
->whereHas('ratings')
->orderByDesc('document_popularity_scores.score')
->take($this->limit)
->get()
->each
->setRelation('author', $this->author);
}
}
// Usage
// ...
$query = new AuthorPopularBooksQuery($author);
// Get a non-blocking cache result in the web endpoint.
resolve(AsyncCache::class)->get($query);
// Get a blocking cache result in the API endpoint.
resolve(SyncCache::class)->get($query);
// [...]
use StuDocu\CacheableEntities\Contracts\SerializableCacheable;
class AuthorPopularBooksQuery implements Cacheable, SerializableCacheable
{
// [...]
/**
* @param Collection<Book> $value
* @return array<int>
*/
public function serialize(mixed $value): array
{
// `$value` represents the computed value of this query; it will be what we will get when calling self::get().
return $value->pluck('id')->all();
}
/**
* @param int[] $value
* @return Collection<int, Book>
*/
public function unserialize(mixed $value): Collection
{
// `$value` represents what we've already cached previously, it will the result of self self::serialize(...)
$booksFastAccess = array_flip($value);
$books = Book::query()
->findMany($value)
->sortBy(fn (Book $book) => $booksFastAccess[$book->id] ?? 999)
->values();
$this->setRelations($books);
return $books;
}
/**
* @param ReturnStructure $books
*/
private function setRelations(Collection $books): void
{
$books->each->setRelation('author', $this->author);
// Generally speaking, you can do eager loading and such in a similar fashion (for ::get and ::unserialize).
}
}
// Usage is still unchanged.
$query = new AuthorPopularBooksQuery($author);
// Get a non-blocking cache result in the web endpoint.
resolve(\StuDocu\CacheableEntities\AsyncCache::class)->get($query);
// Get a blocking cache result in the API endpoint.
resolve(\StuDocu\CacheableEntities\SyncCache::class)->get($query);
/**
* @return ReturnStructure
*
* @throws CorruptSerializedCacheValueException
*/
public function unserialize(mixed $value, mixed $default = null): Collection
{
// Corrupt format cached
if (! is_array($value)) {
throw new CorruptSerializedCacheValueException();
}
if (empty($value)) {
return Collection::empty();
}
$books = Book::query()->findMany($value);
$this->eagerLoadRelations($books);
return $books;
}
// Retaining the original order with array_search
$books = Book::query()
->findMany($value)
->sortBy(fn (Book $book) => array_search($book->id, $value))
->values();
// Retaining the original order with array_flip.
// A faster alternative than the above, using direct array access instead of `array_search`.`
$booksFastAccess = array_flip($value);
$book = Book::query()
->findMany($value)
->get()
->sortBy(fn (Book $book) => $booksFastAccess[$book->id] ?? 999)
->values();
// Retaining the original order with SQL.
$books = Book::query()
->orderByRaw(DB::raw('FIELD(id, ' . implode(',', $value) . ')'))
->get();
$query = new AuthorPopularBooks($author);
// Invalidate the cache (for example, in an event listener).
resolve(\StuDocu\CacheableEntities\SyncCache::class)->forget($query);
use Illuminate\Database\Eloquent\Collection;
use StuDocu\CacheableEntities\Contracts\SupportsDefaultValue;
class AuthorPopularBooks implements Cacheable, SupportsDefaultValue
{
public function getCacheMissValue(): Collection
{
return Collection::empty();
}
}
// [...]
use StuDocu\CacheableEntities\Concerns\SelfCacheable;
class AuthorPopularBooksQuery implements Cacheable, SerializableCacheable
{
use SelfCacheable;
// [...]
}
$query = new AuthorPopularBooksQuery($author);
// Get a non-blocking cache result in the web endpoint.
$query->getCachedAsync();
// Get a blocking cache result in the API endpoint.
$query->getCached();
// Forget the cached value.
$query->forgetCache();