ctw / ctw-middleware-pagecache
This PSR-15 middleware provides full page caching for Mezzio applications.
Installs: 16
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/ctw/ctw-middleware-pagecache
Requires
- php: ^8.3
- ctw/ctw-middleware: ^4.0
- laminas/laminas-cache: ^3.1
- laminas/laminas-cache-storage-adapter-filesystem: ^2.0
- laminas/laminas-diactoros: ^2.11
- mezzio/mezzio-fastroute: ^3.1
- mezzio/mezzio-session: ^1.4
- psr/container: ^1.0 || ^2.0
Requires (Dev)
- ctw/ctw-qa: ^5.0
- phpunit/phpunit: ^12.0
- symfony/var-dumper: ^7.0
- dev-master
- 4.0.4
- 4.0.3
- 4.0.2
- 4.0.1
- 4.0.0
- 3.0.25
- 3.0.24
- 3.0.23
- 3.0.22
- 3.0.21
- 3.0.20
- 3.0.19
- 3.0.18
- 3.0.17
- 3.0.16
- 3.0.15
- 3.0.14
- 3.0.13
- 3.0.12
- 3.0.11
- 3.0.10
- 3.0.9
- 3.0.8
- 3.0.7
- 3.0.6
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 1.0.15
- 1.0.14
- 1.0.13
- 1.0.12
- 1.0.11
- 1.0.10
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
This package is auto-updated.
Last update: 2025-11-27 10:12:06 UTC
README
PSR-15 middleware providing full page caching for Mezzio applications with configurable caching strategies and cache ID generators.
Introduction
Why This Library Exists
Dynamic web pages that don't change frequently can benefit enormously from full page caching. Instead of executing PHP code, querying databases, and rendering templates for every request, cached responses are served directly from storage.
This middleware provides application-level page caching with:
- Strategy-based caching: Define which routes should be cached using route name matching
- Pluggable ID generators: Generate cache keys from full URIs, request URIs, or custom logic
- Laminas Cache integration: Uses Laminas Cache adapters for flexible storage backends
- Response serialization: Caches complete HTTP responses including headers and body
- Cache status headers: Adds
X-Page-Cache: HitorMissheader for debugging
Problems This Library Solves
- Unnecessary computation: Static or semi-static pages re-render on every request
- Database load: Repeated queries for unchanged content strain database resources
- Response latency: Complex pages with multiple service calls have high response times
- Server scaling costs: Without caching, handling traffic spikes requires more servers
- Inconsistent caching: Ad-hoc caching implementations vary across the application
Where to Use This Library
- Content-heavy sites: Blogs, news sites, documentation pages
- Marketing pages: Landing pages, product pages, company information
- Semi-static content: Pages that change infrequently (hourly, daily)
- High-traffic routes: Cache popular endpoints to handle traffic spikes
- Read-heavy applications: Sites where reads vastly outnumber writes
Design Goals
- Route-based strategy: Cache specific routes rather than all requests
- Transparent operation: Cached responses are indistinguishable from fresh ones
- Storage agnostic: Works with any Laminas Cache storage adapter
- Configurable TTL: Set expiration times per cache backend configuration
- Debug visibility:
X-Page-Cacheheader shows cache hit/miss status
Requirements
- PHP 8.3 or higher
- ctw/ctw-middleware ^4.0
- laminas/laminas-cache ^3.1
- laminas/laminas-cache-storage-adapter-filesystem ^2.0
- mezzio/mezzio-fastroute ^3.1
- mezzio/mezzio-session ^1.4
Installation
Install by adding the package as a Composer requirement:
composer require ctw/ctw-middleware-pagecache
Usage Examples
Basic Pipeline Registration (Mezzio)
use Ctw\Middleware\PageCacheMiddleware\PageCacheMiddleware; // In config/pipeline.php - place after routing, before dispatch $app->pipe(PageCacheMiddleware::class);
ConfigProvider Registration
// config/config.php return [ // ... \Ctw\Middleware\PageCacheMiddleware\ConfigProvider::class, ];
Cache Status Header
Every response includes the cache status:
HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 X-Page-Cache: Hit
| Header Value | Description |
|---|---|
Hit |
Response served from cache |
Miss |
Response generated fresh, then cached |
Caching Strategies
RouteNameStrategy
Cache pages based on route names:
use Ctw\Middleware\PageCacheMiddleware\Strategy\RouteNameStrategy\RouteNameStrategy; // Configure routes to cache $strategy = new RouteNameStrategy(); $strategy->setNames([ 'home', 'about', 'blog.list', 'product.detail', ]);
Cache ID Generators
FullUriIdGenerator
Generates cache IDs from the complete URI including scheme, host, path, and query string:
use Ctw\Middleware\PageCacheMiddleware\IdGenerator\FullUriIdGenerator\FullUriIdGenerator; // https://example.com/page?id=1 → hashed cache ID
RequestUriGenerator
Generates cache IDs from the request URI path only:
use Ctw\Middleware\PageCacheMiddleware\IdGenerator\RequestUriGenerator\RequestUriGenerator; // /page?id=1 → hashed cache ID
Enabling/Disabling Cache
The cache can be enabled or disabled at runtime:
$middleware->setEnabled(true); // Enable caching $middleware->setEnabled(false); // Disable caching (bypass)
Cache Flow
Request → Middleware → Strategy.shouldCache()?
├─ No → Handler → Response
└─ Yes → Cache.get(id)?
├─ Hit → Cached Response
└─ Miss → Handler → Cache.set(id) → Response
Response Header Example
curl -I https://example.com/ # First request (cache miss): # X-Page-Cache: Miss # Subsequent requests (cache hit): # X-Page-Cache: Hit