External Cache
August 25, 2026 ยท View on GitHub
Back to root overview: README.md
tc-lib-pdf can reuse generated font subsets and processed images across Tcpdf instances and PHP processes through an optional external cache that you provide.
No cache backend is shipped: you implement an interface that bridges to your own store (filesystem, APCu, Redis, a PSR-16 cache, ...). Caching is disabled by default.
One cache instance is reused by every cacheable subsystem (font subsets and images), so a single backend, connection, and configuration serves them all.
The CacheInterface
Implement Com\Tecnick\Pdf\Cache\CacheInterface:
namespace Com\Tecnick\Pdf\Cache;
interface CacheInterface
{
public function get(string $key): mixed; // stored value, or null on a miss
public function set(string $key, mixed $value): void;
}
Both methods MUST be best-effort and MUST NOT throw: a backend miss or transient failure must surface as null (on get) or a silent no-op (on set). The font and image libraries call the cache directly and do not catch exceptions, so a throwing implementation will break PDF generation.
Enabling the Cache
Pass your implementation as the cache argument of the Tcpdf constructor (the last parameter):
$cache = new MyRedisCache(); // implements Com\Tecnick\Pdf\Cache\CacheInterface
$pdf = new \Com\Tecnick\Pdf\Tcpdf(
unit: 'mm',
subsetfont: true, // required for the font subset cache to be exercised
cache: $cache,
);
A minimal in-memory implementation:
use Com\Tecnick\Pdf\Cache\CacheInterface;
$cache = new class implements CacheInterface {
/** @var array<string, mixed> */
private array $store = [];
public function get(string $key): mixed
{
return $this->store[$key] ?? null;
}
public function set(string $key, mixed $value): void
{
$this->store[$key] = $value;
}
};
What Gets Cached
| Subsystem | Type constant | Cached value | Key prefix |
|---|---|---|---|
| Font subsets | CacheInterface::TYPE_FONT | Raw subset font program (string, uncompressed) | tc-lib-pdf-font:subset:v2: |
| Images | CacheInterface::TYPE_IMAGE | Processed image snapshot (array) | tc-lib-pdf-image:v2: |
Keys are already namespaced and schema-versioned by each sub-library, so a single shared store is collision-safe. The font subset cache is only consulted when font subsetting is enabled (subsetfont: true).
The library never evicts entries: expiration, size limits, and (de)serialization are entirely the backend's responsibility. When an implementation deserializes data it MUST disable object restoration, e.g. unserialize($data, ['allowed_classes' => false]).
Caching Only Some Types
To cache only a subset of the subsystems, implement Com\Tecnick\Pdf\Cache\SelectiveCacheInterface (which extends CacheInterface) and report which types you handle:
namespace Com\Tecnick\Pdf\Cache;
interface SelectiveCacheInterface extends CacheInterface
{
/** @param CacheInterface::TYPE_* $type */
public function supports(string $type): bool;
}
When supports() returns false for a type, that type is disabled entirely: the cache is never queried or written for it, and your implementation never receives its data. A plain CacheInterface (without supports()) caches every type.
For example, to cache font subsets but never images:
use Com\Tecnick\Pdf\Cache\CacheInterface;
use Com\Tecnick\Pdf\Cache\SelectiveCacheInterface;
$cache = new class implements SelectiveCacheInterface {
/** @var array<string, mixed> */
private array $store = [];
public function supports(string $type): bool
{
return $type === CacheInterface::TYPE_FONT;
}
public function get(string $key): mixed
{
return $this->store[$key] ?? null;
}
public function set(string $key, mixed $value): void
{
$this->store[$key] = $value;
}
};
Security
The cache store is a trust boundary. Cached values are embedded verbatim into generated PDFs, so anyone able to write to the backend can influence document output. Use a store only your application can write to, and always deserialize with object restoration disabled (['allowed_classes' => false]).