PHPackages                             ctw/ctw-middleware-pagecache - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. ctw/ctw-middleware-pagecache

ActiveLibrary[Caching](/categories/caching)

ctw/ctw-middleware-pagecache
============================

This PSR-15 middleware provides full page caching for Mezzio applications.

4.0.4(5mo ago)316BSD-3-ClausePHPPHP ^8.3CI passing

Since Mar 17Pushed 5mo ago1 watchersCompare

[ Source](https://github.com/jonathanmaron/ctw-middleware-pagecache)[ Packagist](https://packagist.org/packages/ctw/ctw-middleware-pagecache)[ RSS](/packages/ctw-ctw-middleware-pagecache/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (10)Versions (48)Used By (0)

Package "ctw/ctw-middleware-pagecache"
======================================

[](#package-ctwctw-middleware-pagecache)

[![Latest Stable Version](https://camo.githubusercontent.com/00630e6f8c8238e43ccd3080ca7f5ece58e250dc5900d8fd82db4678c23b480a/68747470733a2f2f706f7365722e707567782e6f72672f6374772f6374772d6d6964646c65776172652d7061676563616368652f762f737461626c65)](https://packagist.org/packages/ctw/ctw-middleware-pagecache)[![GitHub Actions](https://github.com/jonathanmaron/ctw-middleware-pagecache/actions/workflows/tests.yml/badge.svg)](https://github.com/jonathanmaron/ctw-middleware-pagecache/actions/workflows/tests.yml)[![Scrutinizer Build](https://camo.githubusercontent.com/a38e3a18a3fc968a42f4d09943eb0f78cb19d632d3d16717d87124abe3f26a2d/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6a6f6e617468616e6d61726f6e2f6374772d6d6964646c65776172652d7061676563616368652f6261646765732f6275696c642e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/jonathanmaron/ctw-middleware-pagecache/build-status/master)[![Scrutinizer Quality](https://camo.githubusercontent.com/f6f65bceafd1a5e83a74c21462adaa81319ede8bd3d41672b361af7fba327595/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6a6f6e617468616e6d61726f6e2f6374772d6d6964646c65776172652d7061676563616368652f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/jonathanmaron/ctw-middleware-pagecache/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/32954fa9ff70b1648a5089e02bc29e9b9191146c333865a8ec8d03ca99ec2cc1/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6a6f6e617468616e6d61726f6e2f6374772d6d6964646c65776172652d7061676563616368652f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/jonathanmaron/ctw-middleware-pagecache/?branch=master)

PSR-15 middleware providing full page caching for Mezzio applications with configurable caching strategies and cache ID generators.

Introduction
------------

[](#introduction)

### Why This Library Exists

[](#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: Hit` or `Miss` header for debugging

### Problems This Library Solves

[](#problems-this-library-solves)

1. **Unnecessary computation**: Static or semi-static pages re-render on every request
2. **Database load**: Repeated queries for unchanged content strain database resources
3. **Response latency**: Complex pages with multiple service calls have high response times
4. **Server scaling costs**: Without caching, handling traffic spikes requires more servers
5. **Inconsistent caching**: Ad-hoc caching implementations vary across the application

### Where to Use This Library

[](#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

[](#design-goals)

1. **Route-based strategy**: Cache specific routes rather than all requests
2. **Transparent operation**: Cached responses are indistinguishable from fresh ones
3. **Storage agnostic**: Works with any Laminas Cache storage adapter
4. **Configurable TTL**: Set expiration times per cache backend configuration
5. **Debug visibility**: `X-Page-Cache` header shows cache hit/miss status

Requirements
------------

[](#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
------------

[](#installation)

Install by adding the package as a [Composer](https://getcomposer.org) requirement:

```
composer require ctw/ctw-middleware-pagecache
```

Usage Examples
--------------

[](#usage-examples)

### Basic Pipeline Registration (Mezzio)

[](#basic-pipeline-registration-mezzio)

```
use Ctw\Middleware\PageCacheMiddleware\PageCacheMiddleware;

// In config/pipeline.php - place after routing, before dispatch
$app->pipe(PageCacheMiddleware::class);
```

### ConfigProvider Registration

[](#configprovider-registration)

```
// config/config.php
return [
    // ...
    \Ctw\Middleware\PageCacheMiddleware\ConfigProvider::class,
];
```

### Cache Status Header

[](#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 ValueDescription`Hit`Response served from cache`Miss`Response generated fresh, then cached### Caching Strategies

[](#caching-strategies)

#### RouteNameStrategy

[](#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

[](#cache-id-generators)

#### FullUriIdGenerator

[](#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

[](#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

[](#enablingdisabling-cache)

The cache can be enabled or disabled at runtime:

```
$middleware->setEnabled(true);  // Enable caching
$middleware->setEnabled(false); // Disable caching (bypass)
```

### Cache Flow

[](#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

[](#response-header-example)

```
curl -I https://example.com/

# First request (cache miss):
# X-Page-Cache: Miss

# Subsequent requests (cache hit):
# X-Page-Cache: Hit
```

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance71

Regular maintenance activity

Popularity9

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity80

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~37 days

Recently: every ~131 days

Total

47

Last Release

166d ago

Major Versions

1.0.15 → 3.0.02022-07-07

3.0.25 → 4.0.02024-06-18

PHP version history (5 changes)1.0.0PHP ^7.4 || ^8.0

1.0.3PHP ^7.4

3.0.0PHP ^8.0

3.0.9PHP ^8.1

4.0.0PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/18d8bc9bdee8ab1b0cfccce6a06d2438acbed3a58b0046c4834c5678f6769342?d=identicon)[jonathanmaron](/maintainers/jonathanmaron)

---

Top Contributors

[![jonathanmaron](https://avatars.githubusercontent.com/u/298462?v=4)](https://github.com/jonathanmaron "jonathanmaron (65 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/ctw-ctw-middleware-pagecache/health.svg)

```
[![Health](https://phpackages.com/badges/ctw-ctw-middleware-pagecache/health.svg)](https://phpackages.com/packages/ctw-ctw-middleware-pagecache)
```

###  Alternatives

[cakephp/cakephp

The CakePHP framework

8.8k18.5M1.6k](/packages/cakephp-cakephp)[infocyph/intermix

A Collection of useful PHP class functions.

136.4k1](/packages/infocyph-intermix)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
