PHPackages                             ctw/ctw-middleware - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. ctw/ctw-middleware

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

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

This packages provides common functionality for the other PSR-15 ctw/ctw-middleware-\* packages.

4.0.6(5mo ago)11.0k10BSD-3-ClausePHPPHP ^8.3CI passing

Since Mar 13Pushed 5mo ago1 watchersCompare

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

READMEChangelogDependencies (8)Versions (37)Used By (10)

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

[](#package-ctwctw-middleware)

[![Latest Stable Version](https://camo.githubusercontent.com/57cf3a03679e86e7951e0543d6a646a1abb16218e3839f63e200861c02947e63/68747470733a2f2f706f7365722e707567782e6f72672f6374772f6374772d6d6964646c65776172652f762f737461626c65)](https://packagist.org/packages/ctw/ctw-middleware)[![GitHub Actions](https://github.com/jonathanmaron/ctw-middleware/actions/workflows/tests.yml/badge.svg)](https://github.com/jonathanmaron/ctw-middleware/actions/workflows/tests.yml)[![Scrutinizer Build](https://camo.githubusercontent.com/5b3b2c052421e4826258380f7adfddd489799e1b4e661ef2067cb0569f3c4156/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6a6f6e617468616e6d61726f6e2f6374772d6d6964646c65776172652f6261646765732f6275696c642e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/jonathanmaron/ctw-middleware/build-status/master)[![Scrutinizer Quality](https://camo.githubusercontent.com/fe90f94e9b8a362f7062c1cc2979c8e7e724ebe7faa8ca7e31e44480fc35df5c/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6a6f6e617468616e6d61726f6e2f6374772d6d6964646c65776172652f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/jonathanmaron/ctw-middleware/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/766f560cf7f54dec689638f569e323f5bbccc158078007c9e7cc75f5d0a32ebf/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6a6f6e617468616e6d61726f6e2f6374772d6d6964646c65776172652f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/jonathanmaron/ctw-middleware/?branch=master)

Abstract base class providing shared functionality for the ctw/ctw-middleware-\* PSR-15 middleware packages.

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

[](#introduction)

### Why This Library Exists

[](#why-this-library-exists)

Modern PHP applications built on frameworks like Mezzio leverage PSR-15 middleware for request/response processing. When building multiple middleware components that share common functionality, duplicating code across packages leads to maintenance burden and inconsistencies.

This library provides a centralized `AbstractMiddleware` base class that:

- Implements `Psr\Http\Server\MiddlewareInterface` for PSR-15 compliance
- Provides utility methods for detecting HTML responses via Content-Type headers
- Offers statistics calculation for middleware that transform HTML content (minification, tidying)
- Establishes a consistent foundation for the entire ctw/ctw-middleware-\* family

### Problems This Library Solves

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

1. **Code duplication**: Without a shared base, each middleware would implement its own HTML detection and statistics logic
2. **Inconsistent behavior**: Different implementations of content-type checking could lead to subtle bugs
3. **Maintenance overhead**: Bug fixes or improvements would need to be replicated across multiple packages
4. **Missing PSR compliance**: Ensures all derived middleware properly implements `MiddlewareInterface`

### Where to Use This Library

[](#where-to-use-this-library)

- **As a dependency**: All `ctw/ctw-middleware-*` packages depend on this library
- **Custom middleware**: Extend `AbstractMiddleware` when building your own HTML-processing middleware
- **HTML response detection**: Use `containsHtml()` to check if a response contains HTML content
- **Transformation statistics**: Use `getSuffixStatistics()` to generate size comparison metrics

### Design Goals

[](#design-goals)

1. **Minimal footprint**: Only essential shared functionality, no bloat
2. **PSR-15 compliant**: Implements the standard middleware interface
3. **Type-safe**: Full `declare(strict_types=1)` support
4. **Extensible**: Abstract class designed to be extended, not instantiated directly
5. **Zero configuration**: Works out of the box with sensible defaults

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

[](#requirements)

- PHP 8.3 or higher
- ext-mbstring

Installation
------------

[](#installation)

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

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

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

[](#usage-examples)

### Extending AbstractMiddleware

[](#extending-abstractmiddleware)

```
use Ctw\Middleware\AbstractMiddleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

class MyCustomMiddleware extends AbstractMiddleware
{
    public function process(
        ServerRequestInterface $request,
        RequestHandlerInterface $handler
    ): ResponseInterface {
        $response = $handler->handle($request);

        // Only process HTML responses
        if (!$this->containsHtml($response)) {
            return $response;
        }

        // Your HTML processing logic here
        $original = $response->getBody()->getContents();
        $modified = $this->transformHtml($original);

        // Get statistics for the HTML comment suffix
        [$in, $out, $diff] = $this->getSuffixStatistics($original, $modified);

        // Append statistics comment
        $modified .= PHP_EOL . sprintf(self::HTML_SUFFIX, $in, $out, $diff);

        // Return modified response
        // ...
    }
}
```

### HTML Detection

[](#html-detection)

The `containsHtml()` method checks for `text/html` or `application/xhtml` in the `Content-Type` header:

```
if ($this->containsHtml($response)) {
    // Process HTML content
}
```

### Transformation Statistics

[](#transformation-statistics)

For middleware that transforms HTML (minification, beautification), use `getSuffixStatistics()`:

```
[$inputBytes, $outputBytes, $percentReduction] = $this->getSuffixStatistics($original, $transformed);

// Appends comment like:
```

###  Health Score

49

—

FairBetter than 95% of packages

Maintenance70

Regular maintenance activity

Popularity19

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity79

Established project with proven stability

 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 ~50 days

Recently: every ~131 days

Total

35

Last Release

174d ago

Major Versions

1.0.4 → 2.0.02022-02-13

2.0.0 → 3.0.72022-07-07

3.0.21 → 4.0.02024-06-18

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

3.0.7PHP ^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 (54 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[cakephp/cakephp

The CakePHP framework

8.8k18.5M1.6k](/packages/cakephp-cakephp)[shlinkio/shlink

A self-hosted and PHP-based URL shortener application with CLI and REST interfaces

4.8k4.3k](/packages/shlinkio-shlink)[jaxon-php/jaxon-core

Jaxon is an open source PHP library for easily creating Ajax web applications

73142.3k25](/packages/jaxon-php-jaxon-core)[flarum/core

Delightfully simple forum software.

211.3M1.9k](/packages/flarum-core)[laminas/laminas-paginator

Paginate collections of data from arbitrary sources

245.7M84](/packages/laminas-laminas-paginator)[rareloop/lumberjack-core

A powerful MVC framework for the modern WordPress developer. Write better, more expressive and easier to maintain code

42155.0k19](/packages/rareloop-lumberjack-core)

PHPackages © 2026

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