dragon-code/laravel-cache

缓存操作改进接口

3.12.0 2024-03-13 08:15 UTC

README

Laravel Cache

Stable Version Total Downloads Github Workflow Status License

安装

要获取最新版本的 Smart Cache,只需使用 Composer 引入项目

composer require dragon-code/laravel-cache

或者手动更新 composer.json 中的 require 块并运行 composer update

{
    "require": {
        "dragon-code/laravel-cache": "^3.11"
    }
}

使用

键和标签

除了传递显式值之外,您还可以将对象和数组传递给 keystags 方法。

例如

use DragonCode\Cache\Services\Cache;
use Tests\Fixtures\Dto\DtoObject;
use Tests\Fixtures\Simple\CustomObject;

$arr1 = ['foo', 'bar'];
$arr2 = new ArrayObject(['foo', 'bar']);
$arr3 = DtoObject::make(['foo' => 'Foo', 'bar'=> 'Bar']);
$arr4 = new CustomObject();

Cache::make()->key($arr1)->tags($arr1);
Cache::make()->key($arr2)->tags($arr3);
Cache::make()->key($arr2)->tags($arr3);
Cache::make()->key($arr4)->tags($arr4);

Cache::make()
    ->key([$arr1, $arr2, $arr3, $arr4, 'foo', 'bar'])
    ->tags([$arr1, $arr2, $arr3, $arr4, 'foo', 'bar']);

对象和数组的解包和处理如下

use DragonCode\Cache\Services\Cache;
use Tests\Fixtures\Dto\DtoObject;
use Tests\Fixtures\Simple\CustomObject;

['Foo', 'Bar'];
// as key: ['Foo', 'Bar']
// as tag: ['foo', 'bar']

new ArrayObject(['Foo', 'Bar']);
// as key: ['Foo', 'Bar']
// as tag: ['foo', 'bar']

DtoObject::make(['foo' => 'Foo', 'bar'=> 'Bar']);
// as key: ['Foo', 'Bar']
// as tag: ['foo', 'bar']

new CustomObject();
// as key: ['Foo']
// as tag: ['foo']

键处理

由于与缓存键编译相关的主要问题,这个包解决了它。

通过传递值给 keys 方法,我们得到一个准备好的键作为输出。

通过 key=value 的值形成哈希,这允许在传递相同对象时避免冲突。

在传递嵌套数组的情况下,键是根据 key1.key2=value 的原则形成的,其中 key1key2 是每个嵌套数组的键。

例如

use DragonCode\Cache\Services\Cache;

Cache::make()->key('foo', 'bar', [null, 'baz', 'baq']);

// Key is `d76f2bde023f5602ae837d01f4ec1876:660a13c00e04c0d3ffb4dbf02a84a07a:6fc3659bd986e86534c6587caf5f431a:bd62cbee62e027d0be4b1656781edcbf`

这意味着在写入缓存时,将使用树形视图。

例如

use DragonCode\Cache\Services\Cache;

Cache::make()->key('foo', 'foo')->put('Foo');
Cache::make()->key('foo', 'bar')->put('Bar');
Cache::make()->key('baz')->put('Baz');

// d76f2bde023f5602ae837d01f4ec1876:
//     086f76c144511e1198c29a261e87ca50: Foo
//     660a13c00e04c0d3ffb4dbf02a84a07a: Bar
// 1b9829f3bd21835a15735f3a65cc75e9: Baz

禁用键哈希

在某些情况下,您需要禁用键哈希机制。为此,只需调用 hashKey(false) 方法

use DragonCode\Cache\Services\Cache;

Cache::make()->key('foo', 'foo')->hashKey(false)->put('Foo');
Cache::make()->key('foo', 'bar')->hashKey(false)->put('Bar');
Cache::make()->key('baz')->hashKey(false)->put('Baz');

// 0=foo:
//     1=foo: Foo
//     1=bar: Bar
// 0=baz: Baz
use DragonCode\Cache\Services\Cache;

Cache::make()->key([
            ['foo' => 'Foo'],
            ['bar' => 'Bar'],
            [['Baz', 'Qwerty']],
])->hashKey(false)->put('Baz');

// 0.foo=Foo:1.bar=Bar:2.0.0=Baz:2.0.1=Qwerty

与认证

在某些情况下,需要将缓存绑定到某些用户。为此,我们添加了 withAuth 助手。

use DragonCode\Cache\Services\Cache;
use Illuminate\Support\Facades\Auth;

Cache::make()->withAuth()->key('foo', 'bar');

// instead of
Cache::make()->key(get_class(Auth::user()), Auth::id(), 'foo', 'bar');

在调用 withAuth 方法处理请求时,绑定不仅通过标识符进行,还通过模型类引用,因为项目可以有多个具有授权可能的模型。

例如,App\Models\EmployeeApp\Models\User

当启用时

基本

use DragonCode\Cache\Services\Cache;

$cache = Cache::make()->key('foo', 'bar', ['baz', 'baq']);

$cache->put(static fn() => 'Some value');
// or
$cache->put('Some value');
// Contains cached `Some value`

$cache->remember(static fn() => 'Some value');
// or
$cache->remember('Some value');
// Contains cached `Some value`

$cache->rememberForever(static fn() => 'Some value');
// or
$cache->rememberForever('Some value');
// Contains cached `Some value`

$cache->get();
// Returns cached `Some value`

$cache->has();
// Returns `true`

$cache->doesntHave();
// Returns `false`

$cache->forget();
// Will remove the key from the cache.

$cache->flush();
// Clears keys or tags by value
use DragonCode\Cache\Services\Cache;
use App\Models\User;

$user = User::first();

$cache = Cache::make()->key('foo');

$cache->put(static fn() => $user);
// or
$cache->put($user);
// Contains cached `$user`

$cache->remember(static fn() => $user);
// or
$cache->remember($user);
// Contains cached `$user`

$cache->rememberForever(static fn() => $user);
// or
$cache->rememberForever($user);
// Contains cached `$user`

$cache->get();
// Returns User model

$cache->has();
// Returns `true`

$cache->doesntHave();
// Returns `false`

$cache->forget();
// Will remove the key from the cache.

$cache->flush();
// Clears keys or tags by value

方法调用链

有时在处理缓存的过程中,需要在某些动作之间调用某些代码,在这种情况下,call 方法将派上用场

use DragonCode\Cache\Services\Cache;

$cache = Cache::make()->key('foo');
$warmUp = false;

$cache
    ->call(fn (Cache $cache) => $cache->forget(), $warmUp)
    ->call(fn () => $someService->someMethod())
    ->remember('foo');

此外,forget 方法现在返回 Cache 对象的实例,因此可以像这样使用

use DragonCode\Cache\Services\Cache;

$cache = Cache::make()->key('foo');

$cache
    ->forget()
    ->call(fn () => $someService->someMethod())
    ->remember('foo');

之前,您必须使用以下序列

use DragonCode\Cache\Services\Cache;

$cache = Cache::make()->key('foo');
$warmUp = false;

if ($warmUp) {
    $cache->forget();
}

$someService->someMethod()

$cache->remember('foo');

自定义 TTL

默认情况下,缓存将写入 1 天。

缓存将写入指定的分钟数、秒数或 DateTimeInterface 实例。

时间偏移的方向无关紧要。在处理过程中,值被转换为 abs()

按分钟
use Carbon\Carbon;
use DateTime;
use DragonCode\Cache\Services\Cache;
use DragonCode\Cache\Support\Ttl;

Cache::make()->ttl(10);
Cache::make()->ttl('10');
Cache::make()->ttl(fn () => 10);

Cache::make()->ttl(Carbon::now()->addDay());
Cache::make()->ttl(new DateTime('tomorrow'));

Cache::make()->ttl(Ttl::DAY);
Cache::make()->ttl(Ttl::WEEK);
Cache::make()->ttl(Ttl::MONTH);
按秒
use Carbon\Carbon;
use DateTime;
use DragonCode\Cache\Services\Cache;

Cache::make()->ttl(10, false);
Cache::make()->ttl('10', false);
Cache::make()->ttl(fn () => 10, false);

Cache::make()->ttl(Carbon::now()->addDay(), false);
Cache::make()->ttl(new DateTime('tomorrow'), false);
按对象和自定义字符串

您还可以将所有 TTL 值存储在一个地方 - 在 config/cache.php 文件中。

为此,向文件添加一个 ttl 块并 define 对象的 TTL。

之后,您可以使用以下结构

use DragonCode\Cache\Services\Cache;
use Tests\Fixtures\Simple\CustomObject;

Cache::make()->ttl(CustomObject::class);
Cache::make()->ttl(new CustomObject());
Cache::make()->ttl('custom_key');
Cache::make()->ttl((object) ['foo' => 'Foo']);

// You can also specify that these values are in seconds, not minutes:
Cache::make()->ttl(CustomObject::class, false);
Cache::make()->ttl(new CustomObject(), false);
Cache::make()->ttl('custom_key', false);
Cache::make()->ttl((object) ['foo' => 'Foo'], false);

如果找不到值,将采用默认值,您也可以在配置文件中覆盖它。

带有合约

从版本2.9.0开始,我们添加了在对象中动态指定TTL的能力。为此,您需要将DragonCode\Contracts\Cache\Ttl合约实现到您的对象中,并添加一个返回以下类型变量之一的函数:DateTimeInterfaceCarbon\Carbonstringinteger

此方法将允许您根据正在执行的代码动态指定TTL。

例如

use DragonCode\Cache\Services\Cache;
use DragonCode\Contracts\Cache\Ttl;

class Foo implements Ttl
{
    protected $value;

    public function __construct(string $value)
    {
        $this->value = $value;
    }

    public function cacheTtl(): int
    {
        return $this->value === 'foo' ? 123 : 456;
    }
}

Cache::make()->ttl(new Foo('foo'));
// TTL is 7380 seconds

Cache::make()->ttl(new Foo('bar'));
// TTL is 27360 seconds

Cache::make()->ttl(new Foo('foo'), false);
// TTL is 123 seconds

Cache::make()->ttl(new Foo('bar'), false);
// TTL is 456 seconds

标签化

对于支持标签的仓库,键将按标签分开保存。

use DragonCode\Cache\Services\Cache;

$cache = Cache::make()
    ->tags('actor', 'author')
    ->key('foo', 'bar', ['baz', 'baq']);

$cache->put(static fn() => 'Some value');
// or
$cache->put('Some value');
// Contains cached `Some value`

$cache->get();
// Returns cached `Some value`

$cache->has();
// Returns `true`

$cache->doesntHave();
// Returns `false`

$cache->forget();
// Will remove the key from the cache.

$cache->flush();
// Clears keys or tags by value

要检索标签化的缓存项,请将相同的有序标签列表传递给tags方法,然后使用您要检索的键调用get方法。

use DragonCode\Cache\Services\Cache;

$cache = Cache::make()->key('foo', 'bar');

$cache->tags('actor', 'author')->put(static fn() => 'Some value');
// or
$cache->tags('actor', 'author')->put('Some value');
// Contains cached `Some value`

$cache->tags('actor', 'author')->get();
// Returns cached `Some value`

$cache->tags('actor')->get();
// Returns `null`

$cache->tags('author')->get();
// Returns `null`

$cache->tags('author')->flush();
// Clears keys or tags by value

请参阅官方Laravel 文档

当禁用时

传递when = false将不会写入缓存。

use DragonCode\Cache\Services\Cache;

$cache = Cache::make()
    ->when(false)
    ->key('foo', 'bar');

$value = $cache->put(static fn() => 'Some value');
// or
$value = $cache->put('Some value');
// Returns `Some value`

$cache->get();
// Returns `null`

$cache->has();
// Returns `false`

$cache->doesntHave();
// Returns `true`

您还可以在设置中定义是否启用或禁用缓存存储的使用。

例如

// config/cache.php
return [
    'enabled' => [
        // App\Models\Page::class     => true,
        //
        // 'stdClass' => false,
        //
        // 'foo' => false,
    ],
];
use App\Services\Some;use DragonCode\Cache\Services\Cache;

// as string
$cache = Cache::make()->when('foo');

// as class-string
$cache = Cache::make()->when(Some::class);
$cache = Cache::make()->when(static::class);
$cache = Cache::make()->when(self::class);

// as class
$cache = Cache::make()->when(new Some);
$cache = Cache::make()->when($this);

// as stdClass
$cache = Cache::make()->when((object)['foo' => 'Foo']);

许可证

本软件包遵循MIT许可证