1. Go to this page and download the library: Download trm42/cache-decorator library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
trm42 / cache-decorator example snippets
namespace something\nice;
class CachedReportingService {
protected $service;
protected $cache;
public function __construct(ReportingService $service, Cache $cache) {
$this->service = $service;
$this->cache = $cache;
}
public function dailyTotals($date)
{
$key = 'daily-totals-' . $date;
if (!$this->cache->has($key)) {
$results = $this->service->dailyTotals($date);
$this->cache->save($key, $results);
} else {
$results = $this->cache->get($key);
}
return $results;
}
// ... and the same for every other method
}
namespace My\Services;
use Trm42\CacheDecorator\CacheDecorator;
/** @extends CacheDecorator<ReportingService> */
class CachedReportingService extends CacheDecorator {
protected ?string $prefix_key = 'reports';
protected array $excludes = ['recompute']; // methods listed here are never cached
}
$cached = new CachedReportingService(new ReportingService);
$cached->dailyTotals('2026-05-12'); // cache miss → calls ReportingService::dailyTotals
$cached->dailyTotals('2026-05-12'); // cache hit → returns the cached value
$cached = (new CachedReportingService(new ReportingService))
->ttl(600) // TTL in seconds (also DateInterval / DateTimeInterface / null)
->prefix('reports') // cache-key prefix
->withTags(['reports']) // cache tags (tag-capable store)
->tagCleaners(['recompute']) // methods that flush the tags after running
->exclude('debugDump'); // never cache these methods
$cached->totals(); // configured and cached
$cached->reportFor($user); // User implements UrlRoutable → keyed by getRouteKey()
$cached->reportFor($sameUserReloaded); // same route key → cache hit
interface ReportingContract {
public function forMonth(string $month): static; // fluent
public function totals(): array; // cacheable
}
class ReportingService implements ReportingContract { /* ... */ }
/** @extends CacheDecorator<ReportingService> */
class CachedReportingService extends CacheDecorator {
protected ?string $prefix_key = 'reports';
protected array $excludes = ['forMonth']; // fluent method stays on the forward path
}
$cached = new CachedReportingService(new ReportingService);
$cached->forMonth('2026-05')->totals(); // forMonth() returns the decorator; totals() is cached
/** @extends CacheDecorator<ReportingService> */
class CachedReportingService extends CacheDecorator {
protected ?string $prefix_key = 'reports';
#[\Override]
protected function decoratedClass(): ?string
{
return ReportingService::class;
}
}
$cached = new CachedReportingService;
public function findByX($x)
{
$key = $this->generateCacheKey(__FUNCTION__, compact('x'));
$res = $this->getCache($key);
if ($res === $this->cacheMiss()) {
$res = $this->decorated->findX($x);
$this->putCache($key, $res);
}
return $res;
}