CacheMachine
is a simple, lightweight way of managing cache for your Laravel models. Instead of executing queries, you can 'withdraw' cached data using specific keys and simultaneously 'deposit' (save) new cache entries when needed.
One of the key advantages of CacheMachine is its automatic triggering feature during model save or delete actions. This ensures your cache is always up-to-date without requiring manual intervention. For those who prefer more control, you have the flexibility to force cache updates at your discretion. Once created, the cache persists indefinitely until your model undergoes an update.
CacheMachine is particularly well-suited for various use cases, including articles and blog posts, product and pricing information, select fields, translations, user profiles, images etc.
While CacheMachine is designed around caching model queries, it offers versatility. You can incorporate any data into your cache keys, ensuring they stay current with your model updates.
Note: Be mindful - if your models undergo frequent updates, such as every few seconds, it's advisable to configure your own caching methods according to your specific performance requirements.
You are free to use any caching provider you want e.g. Redis, DynamoDB. Refer to Laravel's documentation on caching for further assistance.
This package is compatible with Laravel versions 10 and 11 and PHP versions >= 8.2.
You can install the package via composer:
composer require joshembling/cache-machine
To use CacheMachine, the same structure will apply to each of your models.
- Add the
CacheMachine
trait.
use JoshEmbling\CacheMachine\CacheMachine;
class Post extends Model
{
use CacheMachine;
// ...
}
- Add the
cacheKeys()
method to your model. This must return an array with a structure ofstring => callable
.
use JoshEmbling\CacheMachine\CacheMachine;
class Post extends Model
{
use CacheMachine;
/**
* @var array<string, callable>
*/
public static function cacheKeys(): array
{
$keys = [
// Cache all posts with the eloquent query as the callback
'all_posts' => fn () => self::all(),
];
return $keys;
}
// ...
}
- You may prefer to dynamically refer to your keys as constants or properties within this class.
use JoshEmbling\CacheMachine\CacheMachine;
class Post extends Model
{
use CacheMachine;
const ALL = 'all_posts';
const SELECT = 'select_posts';
/**
* @var array<string, callable>
*/
public static function cacheKeys(): array
{
$keys = [
// Cache all posts
self::ALL => fn () => self::all(),
// Cache all posts in a key => value format
self::SELECT => fn () => self::get()->mapWithKeys(
fn ($type) => [
$type->id => $type->title,
]
),
];
return $keys;
}
// ...
}
Once you have set up your model, you are able to withdraw()
your cache. If it doesn't exist, CacheMachine will automatically deposit
your cache for you when your callback function is valid.
In other words, CacheMachine will fetch from the cache when it exists, or query the database if it doesn't.
// You may pass a string to the withdraw method.
Post::withdraw('all_posts');
// Or one of your model's static properties, relating to a key defined in the `cacheKeys()` method.
Post::withdraw(Post::ALL);
If you would like to manually save to the cache e.g. you have manually added records to your database without triggering model observers, you may execute the following:
Post::forceFetch(Post::ALL)
If your callback functions in your cacheKeys()
return Eloquent queries, you can use any collection method to filter your results. You will not need to query your database once the parent query is cached.
Here is a simple example of what you could do on a blog site:
// Fetch all posts to display on an archive
Post::withdraw('all_posts');
// Display a single blog article
Post::withdraw('all_posts')
->firstWhere('id', 2);
// Filter a user search query
Post::withdraw('all_posts')
->where('title', 'like', '%Laravel%')
->orWhere('published_at', '>', now()->subDays(30))
->map(fn ($post) => strtoupper($post->title))
->sortDesc();
You may wish to enhance your collections even further so you are mitigating any heavy useage of your database. If you want additional features such as pagination, chunks etc. that don't come out of the box with Laravel, I recommend laravel-collection-macros by Spatie.
composer test
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.