| name | acc-create-psr6-cache |
| description | Generates PSR-6 Cache implementation for PHP 8.5. Creates CacheItemPoolInterface and CacheItemInterface implementations with TTL handling and deferred saves. Includes unit tests. |
PSR-6 Cache Generator
Overview
Generates PSR-6 compliant cache implementations following Psr\Cache\CacheItemPoolInterface and Psr\Cache\CacheItemInterface.
When to Use
- Complex caching with cache items as objects
- Need for deferred/batched saves
- Building cache frameworks
- Need for cache item metadata
Generated Components
| Component | Description | Location |
|---|
| CacheItemPool | Pool implementation | src/Infrastructure/Cache/ |
| CacheItem | Item implementation | src/Infrastructure/Cache/ |
| Unit Tests | PHPUnit tests | tests/Unit/Infrastructure/Cache/ |
Template: Cache Item
<?php
declare(strict_types=1);
namespace App\Infrastructure\Cache;
use DateInterval;
use DateTimeImmutable;
use DateTimeInterface;
use Psr\Cache\CacheItemInterface;
final class CacheItem implements CacheItemInterface
{
private mixed $value = null;
private bool $isHit = false;
private ?DateTimeImmutable $expiration = null;
public function __construct(
private readonly string $key,
) {
}
public function getKey(): string
{
return $this->key;
}
public function get(): mixed
{
return $this->isHit ? $this->value : null;
}
public function isHit(): bool
{
return $this->isHit;
}
public function set(mixed $value): static
{
$this->value = $value;
$this->isHit = true;
return $this;
}
public function expiresAt(?DateTimeInterface $expiration): static
{
$this->expiration = $expiration instanceof DateTimeImmutable
? $expiration
: ($expiration !== null
? DateTimeImmutable::createFromInterface($expiration)
: null);
return $this;
}
public function expiresAfter(int|DateInterval|null $time): static
{
if ($time === null) {
$this->expiration = null;
} elseif ($time instanceof DateInterval) {
$this->expiration = (new DateTimeImmutable())->add($time);
} else {
$this->expiration = (new DateTimeImmutable())->modify("+{$time} seconds");
}
return $this;
}
public function getExpiration(): ?DateTimeImmutable
{
return $this->expiration;
}
public function isExpired(): bool
{
if ($this->expiration === null) {
return false;
}
return $this->expiration < new DateTimeImmutable();
}
public function markAsHit(): void
{
$this->isHit = true;
}
public function markAsMiss(): void
{
$this->isHit = false;
}
}
Template: Array Cache Pool
<?php
declare(strict_types=1);
namespace App\Infrastructure\Cache;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;
final class ArrayCachePool implements CacheItemPoolInterface
{
private array $items = [];
private array $deferred = [];
public function getItem(string $key): CacheItemInterface
{
$this->validateKey($key);
if (isset($this->deferred[$key])) {
return clone $this->deferred[$key];
}
if (isset($this->items[])) {
= ->items[];
(!->()) {
;
}
(->items[]);
}
= ();
->();
;
}
{
= [];
( ) {
[] = ->();
}
;
}
{
->();
->()->();
}
{
->items = [];
->deferred = [];
;
}
{
->();
(->items[], ->deferred[]);
;
}
{
( ) {
->();
}
;
}
{
(! CacheItem) {
;
}
->items[->()] = ;
(->deferred[->()]);
;
}
{
(! CacheItem) {
;
}
->deferred[->()] = ;
;
}
{
(->deferred ) {
->();
}
->deferred = [];
;
}
{
( === ) {
();
}
((, )) {
(
,
);
}
}
}
Template: Unit Test
<?php
declare(strict_types=1);
namespace App\Tests\Unit\Infrastructure\Cache;
use App\Infrastructure\Cache\ArrayCachePool;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
#[Group('unit')]
#[CoversClass(ArrayCachePool::class)]
final class ArrayCachePoolTest extends TestCase
{
private ArrayCachePool $pool;
protected function setUp(): void
{
$this->pool = new ArrayCachePool();
}
{
= ->pool->();
::(->());
::(->());
}
{
= ->pool->();
->();
->pool->();
= ->pool->();
::(->());
::(, ->());
}
{
= ->pool->()->();
= ->pool->()->();
->pool->();
->pool->();
::(->pool->()->());
->pool->();
::(->pool->()->());
::(->pool->()->());
}
{
= ->pool->()->();
->pool->();
->pool->();
::(->pool->());
}
{
->pool->(->pool->()->());
->pool->(->pool->()->());
->pool->();
::(->pool->());
::(->pool->());
}
}
Usage Example
<?php
use App\Infrastructure\Cache\ArrayCachePool;
$pool = new ArrayCachePool();
$item = $pool->getItem('user_123');
if (!$item->isHit()) {
$user = $userRepository->find(123);
$item->set($user);
$item->expiresAfter(3600);
$pool->save($item);
}
$user = $item->get();
$item1 = $pool->getItem('key1')->set('value1');
$item2 = $pool->getItem('key2')->set('value2');
$pool->saveDeferred($item1);
$pool->saveDeferred();
->();
Requirements
{
"require": {
"psr/cache": "^3.0"
}
}
See Also
references/templates.md - Redis and file-based implementations
references/examples.md - Integration examples