External Cache

Optional external cache for font subsets and image processing in tc-lib-pdf

Generating font subsets and processing images (decode, resize, re-encode) is computationally expensive. tc-lib-pdf can reuse these results across Tcpdf instances and PHP processes through an optional external cache that you provide.

No cache backend is shipped: you implement a tiny interface that bridges to whatever store you already use (filesystem, APCu, Redis, a PSR-16 cache, and so on). Caching is disabled by default — when no cache is supplied, behavior is unchanged.

One cache instance is reused by every cacheable subsystem (currently font subsets and images, with more possible later), 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 (useful for tests or single-request deduplication):

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

SubsystemType constantCached valueKey prefix
Font subsetsCacheInterface::TYPE_FONTRaw subset font program (string, uncompressed)tc-lib-pdf-font:subset:v2:
ImagesCacheInterface::TYPE_IMAGEProcessed image snapshot (array)tc-lib-pdf-image:v2:

The cached types are also available as the backed enum Com\Tecnick\Pdf\Cache\CacheType (font, image), whose values match the TYPE_* constants.

Keys are already namespaced and schema-versioned by each sub-library, so a single shared store is collision-safe. The prefixes were bumped to v2 when the stored payload schema changed, so entries written by older releases are simply never read. 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, for example 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.

Example — 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]).


Previous: /docs/pdf-import/

Overview: /docs/

Next: /docs/fonts/

 

© 2004-2026 – Nicola Asuni - Tecnick.com - All rights reserved.
sponsor - legal notice - privacy