ruvents/spiral-cache

PSR-{6,16} 兼容的缓存集成

0.1.0 2021-12-17 09:30 UTC

This package is auto-updated.

Last update: 2024-09-17 15:49:23 UTC


README

此包将PSR-6和PSR-16兼容的缓存实现(主要是Symfony实现)集成到Spiral应用程序中。作为额外的好处,它还提供了方便的HTTP响应缓存解决方案。

安装

composer require ruvents/spiral-cache symfony/cache:^5.0 psr/simple-cache

psr/simple-cache是可选的,您只能使用PSR-6兼容的缓存。

symfony/cache是可选的,您可以使用您选择的任何PSR-6实现。

然后,将CacheBootloader添加到您的App.php

use Ruvents\SpiralCache\CacheBootloader;

class App extends Kernel
{
    protected const LOAD = [
        ...
        CacheBootloader::class,
    ]
}

配置

将以下代码放入文件app/config/cache.php

<?php

declare(strict_types=1);

return [
    // Array of named cache pools.
    'pools' => [
        'localCache' => new ArrayAdapter(), // can be any object that implements CacheItemPoolInterface
    ],
    // Optional, default value is 'default'. Item with specified key must be
    // present in 'pools' array.
    'default' => 'localCache',
    // Optional, will use default cache pool if omitted. Item with specified key
    // must be present in 'pools' array.
    'controllerPool' => 'localCache',
];

必须创建默认池,以便包能正常工作。

使用

手动

配置后,您应该能够通过其名称将创建的缓存池注入到您的代码中

use Psr\Cache\CacheItemPoolInterface;

/**
 * @Route('/list', methods="GET")
 */
public function list(CacheItemPoolInterface $localCache): ResponseInterface
{
    if ($localCache->hasItem('list')) {
        return $localCache->getItem('list')->get();
    }

    $response = ...;
    $item = $localCache->getItem('list');
    $item->set($response);
    $localCache->save($item);

    return $response;
}

如果已安装symfony/cache,您可以通过指定CacheInterface将PSR-6缓存实现升级到PSR-16

use Psr\SimpleCache\CacheInterface;

/**
 * @Route('/list', methods="GET")
 */
public function list(CacheInterface $localCache): ResponseInterface
{
    if ($localCache->has('list')) {
        return $localCache->get('list');
    }

    $response = ...;
    $localCache->set('list', $response);

    return $response;
}

如果已安装symfony/cache,您可以注入其缓存实现

use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;

/**
 * @Route('/list', methods="GET")
 */
public function list(CacheInterface $localCache): ResponseInterface
{
    return $localCache->get('list', static function (ItemInterface $item) {
        $item->expiresAfter(3600);
        $response = ...;

        return $response;
    });
}

如果已安装symfony/cache,您可以注入标签感知缓存

use Symfony\Contracts\Cache\TagAwareCacheInterface;
use Symfony\Contracts\Cache\ItemInterface;

/**
 * @Route('/list', methods="GET")
 */
public function list(TagAwareCacheInterface $localCache): ResponseInterface
{
    if ($localCache->hasItem('list')) {
        return $localCache->getItem('list')->get();
    }

    $response = ...;
    $item = $localCache->getItem('list');
    $item->set($response);
    $item->tag(['api.list']);
    $localCache->save($item);

    return $response;
}

使用#[Cached]属性

您可以使用#[Cached]属性从HTTP操作中移除缓存代码。您需要安装Ruvents\SpiralCache\CacheInterceptor才能识别此属性。有关安装详情,请参阅相关文档

以下是如何缓存给定操作的HTTP响应的示例

use Ruvents\SpiralCache\Annotation\Cached;

/**
 * @Route('/list', methods="GET")
 */
#[Cached('+4 hours')]
public function list(): ResponseInterface
{
    $response = ...;
    return $response;
}

方法类的名称、方法名称和请求URI都用于自动生成缓存键。要实现自定义键生成逻辑,请在属性中指定key

use Ruvents\SpiralCache\Annotation\Cached;

/**
 * @Route('/list', methods="GET")
 */
#[Cached('+4 hours', key: [self::class, 'keyGenerator'])]
public function list(): ResponseInterface
{
    $response = ...;
    return $response;
}

public static function keyGenerator(array $context): string
{
    $key = ...; // any logic here
    return $key;
}

如果您想有条件地应用缓存,请指定if键的可调用数组

use Ruvents\SpiralCache\Annotation\Cached;

#[Cached('+4 hours', if: [self::class, 'cacheCondition'])]
public function list(): ResponseInterface
{
    $response = ...;
    return $response;
}

public static function cacheCondition(array $context): string
{
    $key = ...; // any logic here
    return $key;
}

如果已安装symfony/cache并且使用TagAwareCacheInterface作为controllerPool,您可以通过指定tags来选择性地清除缓存项的组

use Ruvents\SpiralCache\Annotation\Cached;

#[Cached('+4 hours', tags: ['api.list'])]
public function list(): ResponseInterface
{
    $response = ...;
    return $response;
}

... somewhere else in code ...

public function clearCache(TagAwareCacheInterface $localCache): string
{
    $localCache->invalidateTags(['api.list']);
}