mahmoud217tr / cacheable
Laravel 包,简化并增强模型和可缓存类的缓存
Requires
- php: ^8.0
- illuminate/cache: ^9.0|^10.0|^11.0
- illuminate/contracts: ^9.0|^10.0|^11.0
- illuminate/support: ^9.0|^10.0|^11.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^2.9
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1||^7.10.0
- orchestra/testbench: ^9.0.0||^8.22.0
- pestphp/pest: ^2.34
- pestphp/pest-plugin-arch: ^2.7
- pestphp/pest-plugin-laravel: ^2.3
- phpstan/extension-installer: ^1.3
- phpstan/phpstan-deprecation-rules: ^1.1
- phpstan/phpstan-phpunit: ^1.3
README
模型和类的轻松增强缓存
Laravel 包,提供了一种流畅且强大的解决方案,用于在您的应用程序中实现缓存。此包简化了缓存 Eloquent 模型和其它类的过程,确保您的 Laravel 应用程序性能和可扩展性得到提升。
目录
安装
通过 Composer 将包安装到您的 Laravel 项目中
composer require mahmoud217tr/cacheable
安装完成后,该包即可准备好供使用。
使用方法
有许多功能和用例,我们将通过以下内容进行总结
1. 可缓存模型
您可以通过实现 CacheableModel
接口并使用 CacheableModelTrait
特性使其模型可缓存,如下例所示
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Mahmoud217TR\Cacheable\Models\Contracts\CacheableModel; use Mahmoud217TR\Cacheable\Models\Traits\CacheableModelTrait; class Post extends Model implements CacheableModel { use CacheableModelTrait; }
这样做后,您的模型将使用
Cacheable Collection
作为集合,该集合扩展了Eloquent Collection
,保留了相同的逻辑并为模型提供缓存功能。
使模型可缓存将为您提供缓存功能
1. 轻松缓存模型记录和集合
您可以使用 cache
方法轻松缓存单个模型记录或记录集合,如下所示
<?php use App\Models\Post; use Illuminate\Support\Facades\Cache; use Mahmoud217TR\Cacheable\Facades; # Caching the first post for 120 seconds Post::first()->cache('first_post', 120); # Caching published posts indefinitely Post::whereNotNull('published_at') ->get() ->cache('published_posts'); # Retrieve cached data using the Cache facade Cache::get('first_post'); Cache::get('published_posts'); # Or using the Cacheable facade Cacheable::get('first_post'); Cacheable::get('published_posts');
2. 自动缓存模型记录
模型可以自动缓存,这意味着所有模型记录在创建、更新或删除时都将被缓存和同步。
注意:此行为可能不适合大型模型或经常更改的模型。根据您的用例明智地使用它。
要启用自动缓存,请覆盖模型中的 isAutoCacheSyncEnabled
方法并返回 true
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Mahmoud217TR\Cacheable\Models\Contracts\CacheableModel; use Mahmoud217TR\Cacheable\Models\Traits\CacheableModelTrait; class Post extends Model implements CacheableModel { use CacheableModelTrait; public static function isAutoCacheSyncEnabled(): bool { return true; } }
现在,自动缓存功能将启用,所有模型记录将自动缓存和更新。
重要:如果您有模块化 Laravel 应用程序或更改了模型的默认目录,您需要进行 额外步骤。
您可以根据以下方式管理缓存的模型
<?php use App\Models\Post; # Get cached posts $posts = Post::getCached(); # Update cached data manually Post::syncCache(); # Flush cached data Post::flushCache(); # Set cached data manually Post::setCache(Post::limit(4)->get());
您还可以通过覆盖 getDataForCaching
方法来控制自动缓存的集合,其默认行为是返回 all
方法的结果
<?php namespace App\Models; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Mahmoud217TR\Cacheable\Models\Contracts\CacheableModel; use Mahmoud217TR\Cacheable\Models\Traits\CacheableModelTrait; class Post extends Model implements CacheableModel { use CacheableModelTrait; public function scopePublished(Builder $query) { $query->whereNotNull('published_at'); } public static function isAutoCacheSyncEnabled(): bool { return true; } protected static function getDataForCaching() { return static::published() ->latest() ->get(); } }
现在,只有发布的帖子将被自动缓存功能缓存,并按最新顺序排列。
您还可以通过覆盖 getCacheTTL
方法来控制缓存的 TTL
<?php namespace App\Models; use DateInterval; use DateTimeInterface; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Mahmoud217TR\Cacheable\Models\Contracts\CacheableModel; use Mahmoud217TR\Cacheable\Models\Traits\CacheableModelTrait; class Post extends Model implements CacheableModel { use CacheableModelTrait; public function scopePublished(Builder $query) { $query->whereNotNull('published_at'); } public static function isAutoCacheSyncEnabled(): bool { return true; } protected static function getDataForCaching() { return static::published() ->latest() ->get(); } protected static function getCacheTTL(): null | int | DateInterval | DateTimeInterface { return 86400; } }
3. 缓存路由模型绑定
您还可以通过简单地使用 CachedRouteBinding
特性来利用缓存的记录用于路由模型绑定
<?php namespace App\Models; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Mahmoud217TR\Cacheable\Models\Contracts\CacheableModel; use Mahmoud217TR\Cacheable\Models\Traits\CacheableModelTrait; use Mahmoud217TR\Cacheable\Models\Traits\CachedRouteBinding; class Post extends Model implements CacheableModel { use CacheableModelTrait; use CachedRouteBinding; public function scopePublished(Builder $query) { $query->whereNotNull('published_at'); } public static function isAutoCacheSyncEnabled(): bool { return true; } protected static function getDataForCaching() { return static::published() ->latest() ->get(); } }
注意:通过覆盖
getDataForCaching
方法修改自动缓存的数据库可能会导致非缓存模型记录出现404 Not Found
。我们将进一步讨论此场景的解决方案。
您可以通过覆盖两个方法来更改用于路由模型绑定的缓存数据
- 您应该覆盖
shouldUseDifferentDataForBinding
方法并返回true
(默认情况下它返回false
)。 - 并且您还应该覆盖
getBindingData
方法,该方法表示要缓存的数据库集合(默认情况下返回null
)。
<?php namespace App\Models; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Mahmoud217TR\Cacheable\Models\Contracts\CacheableModel; use Mahmoud217TR\Cacheable\Models\Traits\CacheableModelTrait; use Mahmoud217TR\Cacheable\Models\Traits\CachedRouteBinding; class Post extends Model implements CacheableModel { use CacheableModelTrait; use CachedRouteBinding; public function scopePublished(Builder $query) { $query->whereNotNull('published_at'); } public static function isAutoCacheSyncEnabled(): bool { return true; } protected static function getDataForCaching() { return static::published() ->latest() ->get(); } protected static function shouldUseDifferentDataForBinding(): bool { return true; } protected static function getBindingData() { return static::all(); } }
现在用于路由模型绑定的数据将以不同的键进行缓存,并具有不同的值,并且将自动同步。
当启用使用不同数据绑定时,您可以通过重写 getBindingCacheTTL
方法来控制路由绑定缓存的 TTL
。
<?php namespace App\Models; use DateInterval; use DateTimeInterface; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Mahmoud217TR\Cacheable\Models\Contracts\CacheableModel; use Mahmoud217TR\Cacheable\Models\Traits\CacheableModelTrait; use Mahmoud217TR\Cacheable\Models\Traits\CachedRouteBinding; class Post extends Model implements CacheableModel { use CacheableModelTrait; use CachedRouteBinding; public function scopePublished(Builder $query) { $query->whereNotNull('published_at'); } public static function isAutoCacheSyncEnabled(): bool { return true; } protected static function getDataForCaching() { return static::published() ->latest() ->get(); } protected static function shouldUseDifferentDataForBinding(): bool { return true; } protected static function getBindingData() { return static::all(); } protected static function getBindingCacheTTL(): null | int| DateInterval | DateTimeInterface { return 3600; } }
您还可以通过重写 shouldUseAlternativeRouteBinding
方法并返回 true
来允许模型使用替代路由绑定方法。
<?php namespace App\Models; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Mahmoud217TR\Cacheable\Models\Contracts\CacheableModel; use Mahmoud217TR\Cacheable\Models\Traits\CacheableModelTrait; use Mahmoud217TR\Cacheable\Models\Traits\CachedRouteBinding; class Post extends Model implements CacheableModel { use CacheableModelTrait; use CachedRouteBinding; public function scopePublished(Builder $query) { $query->whereNotNull('published_at'); } public static function isAutoCacheSyncEnabled(): bool { return true; } protected static function getDataForCaching() { return static::published() ->latest() ->get(); } protected static function shouldUseDifferentDataForBinding(): bool { return true; } protected static function shouldUseDifferentDataForBinding(): bool { return true; } protected static function getBindingData() { return static::all(); } protected static function shouldUseAlternativeRouteBinding(): bool { return true; } }
默认的替代路由绑定解析器是 resolveRouteBinding
方法,可以通过重写 alternativeRouteBinding
方法来自定义。
<?php namespace App\Models; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Mahmoud217TR\Cacheable\Models\Contracts\CacheableModel; use Mahmoud217TR\Cacheable\Models\Traits\CacheableModelTrait; use Mahmoud217TR\Cacheable\Models\Traits\CachedRouteBinding; class Post extends Model implements CacheableModel { use CacheableModelTrait; use CachedRouteBinding; public function scopePublished(Builder $query) { $query->whereNotNull('published_at'); } public static function isAutoCacheSyncEnabled(): bool { return true; } protected static function getDataForCaching() { return static::published() ->latest() ->get(); } protected static function shouldUseDifferentDataForBinding(): bool { return true; } protected static function getBindingData() { return static::all(); } protected static function shouldUseAlternativeRouteBinding(): bool { return true; } protected static function alternativeRouteBinding($value, $field = null) { return parent::customRouteBinding($value, $field); } }
2. 可缓存接口 & 特性
通过使其实现 Cacheable
接口和使用 CachableTrait
特性,您可以轻松地将任何东西设置为可缓存。
<?php namespace App\Classes; use Mahmoud217TR\Cacheable\Contracts\Cacheable; use Mahmoud217TR\Cacheable\Traits\CacheableTrait; class MyCustomClass implements Cacheable { use CacheableTrait; protected string $customAttribute; public function __construct(string $value) { $this->customAttribute = $value; } }
您可以使用缓存功能按如下方式存储对象
<?php use App\Classes\MyCustomClass; $object = new MyCustomClass("data"); # Caching object indefinitely $object->cache('cache_key_2'); # Caching object for 200 seconds $object->cache('cache_key', 200);
3. 可缓存外观
您还可以利用 Cacheable
外观的一些缓存功能,它从 Cache
外观派生了一些功能。
<?php use App\Classes\MyCustomClass; use App\Models\Post; use Mahmoud217TR\Cacheable\Facades\Cacheable; # --- Drived methods from the Cache facade --- # Returns true if cached data was found Cacheable::has('cache_key'); # Returns true if cached data was not found Cacheable::missing('cache_key'); # Returns the cached data, if not found returns a default value Cacheable::get('cache_key', 'default value'); # Caches data for with a given key for amount of time or indefinitely Cacheable::put('cache_key', 'data', 20); # Caches data for 20 seconds Cacheable::set('cache_key', 'data'); # Caches data indefinitely # Invalidate cached data with a given key Cacheable::forget('cache_key'); # --- New features --- # Retrieves cached data by key # Caches the value in the given value with the key if no data found # You can also set a time to live for cache Cacheable::cached('cache_key', 'data', 150); # Returns true if the given model implements the CacheableModel interface Cacheable::isCacheableModel(Post::class); Cacheable::isCacheableModel(Post::first()); # Returns true if the given model implements the Cacheable interface Cacheable::isCacheableClass(MyCustomClass::class); Cacheable::isCacheableClass(new MyCustomClass('data')); # Returns an array of the models that implements CacheableModel interface Cacheable::getCacheableModels();
4. 辅助函数
该包将为您提供新的辅助函数。
is_cacheable_model
辅助函数,用于检查一个模型或其实例是否实现了CacheableModel
接口。is_cacheable_class
辅助函数,用于检查一个类或其实例是否实现了Cacheable
接口。cached
辅助函数,用于检索给定键的缓存数据,如果未找到,则将给定值按给定键缓存,如果提供了存活时间。
<?php use App\Classes\MyCustomClass; use App\Models\Post; # Returns true if the given model implements the CacheableModel interface is_cacheable_model(Post::class); is_cacheable_model(Post::first()); # Returns true if the given model implements the Cacheable interface is_cacheable_class(MyCustomClass::class); is_cacheable_class(new MyCustomClass('data')); cached('cached_array_key', [1, 2, 3]) # Returns [1, 2, 3] cached('cached_array_key') # Returns [1, 2, 3] cached('cached_string_key', "Hello") # Returns "Hello" cached('cached_string_key', "Ops") # Returns "Hello" because data was found
发布
要自定义包的缓存行为,您可以通过在控制台运行以下命令来发布配置文件,将配置文件复制到您的应用程序配置目录:
php artisan vendor:publish --provider="Mahmoud217TR\Cacheable\CacheableServiceProvider"
测试
composer test
变更日志
有关最近更改的更多信息,请参阅变更日志。
安全漏洞
有关如何报告安全漏洞,请查看我们的安全策略。
鸣谢
许可
MIT 许可证 (MIT)。有关更多信息,请参阅许可文件。