mammatus / http-server
🐙 Multi vhost HTTP Server
Package info
github.com/MammatusPHP/http-server
Language:Makefile
Type:composer-plugin
pkg:composer/mammatus/http-server
Requires
- php: ^8.4
- composer-plugin-api: ^2.0.0
- ext-json: ^8.4
- composer/composer: ^2.9.2
- for/http-middleware-psr15-adapter: ^2.0
- mammatus/app: dev-master
- mammatus/groups: ^0.4.0
- mammatus/healthz-vhost: ^0.1.0 || ^0.2.0
- mammatus/http-server-attributes: ^0.1.0 || ^0.2.0 || ^0.3.0
- mammatus/http-server-contracts: ^0.1.0
- mammatus/http-server-webroot: ^0.1.0
- mammatus/kubernetes-attributes: ^1.3.0
- mammatus/kubernetes-events: ^5.2.0
- mammatus/life-cycle-events: ^2.3.0
- nikic/fast-route: 2.0.0-beta1
- nikic/php-parser: ^5.7.0
- psr/container: ^1 || ^2 || ^3
- psr/http-factory: ^1 || ^2 || ^3
- psr/http-message: ^1 || ^2 || ^3
- psr/http-server-middleware: ^1 || ^2 || ^3
- psr/log: ^3.0.2
- react/async: ^4.3.0
- react/cache: ^1.2.0
- react/event-loop: ^1.6.0
- react/http: ^1.11.0
- react/promise: ^3.3.0
- react/socket: ^1.17.0
- realodix/change-case: ^4.2.1
- roave/better-reflection: ^6.66.0
- wyrihaximus/broadcast: ^2.5.0
- wyrihaximus/broadcast-contracts: ^1.3.0
- wyrihaximus/generative-composer-plugin-tooling: ^1.8.2
- wyrihaximus/psr-3-context-logger: ^3.0.0
- wyrihaximus/react-http-middleware-webroot-preload: ^3.0.0
- wyrihaximus/simple-twig: ^2.2.1
Requires (Dev)
- colinodell/psr-testlogger: ^1.3.1
- monolog/monolog: ^3.9.0
- pimple/pimple: ^3.6.0
- shipmonk/dead-code-detector: ^0.14.1 || ^0.15.0 || ^1.0.0
- wyrihaximus/makefiles: ^0.15.4
- wyrihaximus/test-utilities: ^14.5.0
Suggests
- shipmonk/dead-code-detector: This package supports ^1 || ^0.15 || ^0.14.1 by hooking in and marking all listeners as alive
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-16 22:41:54 UTC
README
Async multi-vhost HTTP on ReactPHP and react/http for MammatusPHP applications. mammatus/http-server is a Composer plugin that discovers virtual hosts and route handlers across your project and installed packages, then generates ReactPHP server classes and Kubernetes-oriented Helm values. Generated servers implement LifeCycleHandler and start or stop with Mammatus groups.
Install
To install via Composer, use the command below. Composer picks the latest compatible version and applies a ^ constraint.
composer require mammatus/http-server
The plugin runs on every composer dump-autoload (pre-autoload-dump) and via the composer generate-config script. Both call Mammatus\Http\Server\Composer\Installer::findServers.
How it works
On autoload dump the plugin scans the codebase and installed packages, collects vhosts, HTTP handlers, and optional Kubernetes metadata, then writes generated PHP under the plugin install path (for example vendor/mammatus/http-server/ in an application).
flowchart LR
subgraph discover [Discovery on composer dump]
VhostClasses["Classes implementing Vhost"]
HandlerClasses["Classes with Vhost plus Route attributes"]
Packages["Packages with extra.mammatus.http.server.has-vhosts"]
end
Plugin["mammatus/http-server Plugin"]
Generated["src/Server LifeCycleHandlers"]
Helm["Kubernetes Helm ServerValues"]
discover --> Plugin
Plugin --> Generated
Plugin --> Helm
Generated --> Groups["Mammatus groups start and stop"]
Loading
- Discovery filters:
Plugin::filters()matches packages withextra.mammatus.http.server.has-vhosts, classes implementingVhost, and handler classes that carry both#[Vhost]and#[Route]. - Collection:
Collectoryields servers, handlers, and optionalService/Ingressitems from vhost classes. - Generated output:
Server.php.twigtosrc/Server/{PascalVhostName}.php(oneLifeCycleHandlerper vhost)ServerValues.php.twigtoServerValuesfor Helm integration
- Do not edit generated files manually. They are overwritten on the next install or update (see the banner on
Frontend). - Routing: FastRoute with a on-disk route cache under
var/fast-route/{vhostName}inside generated code. - Per-vhost HTTP stack: request logging, body buffer and parser, optional PSR-15 middleware from the vhost, optional webroot preload middleware, then FastRoute dispatch.
Define a virtual host
Implement Mammatus\Http\Server\Configuration\Vhost: static name(), port(), and webroot() (NoWebroot or a path-backed webroot), plus instance middleware(). Optional #[Group], #[Service], and #[Ingress] on the class feed Helm values generation.
Example from this repository's dev app (FrontendVhost.php):
<?php declare(strict_types=1); namespace Mammatus\DevApp\Http\Server; use Mammatus\Groups\Attributes\Group; use Mammatus\Groups\Type; use Mammatus\Http\Server\Configuration\Vhost; use Mammatus\Http\Server\Configuration\Webroot; use Mammatus\Http\Server\Webroot\NoWebroot; use Mammatus\Kubernetes\Attributes\Ingress; use Mammatus\Kubernetes\Attributes\Service; use Psr\Http\Server\MiddlewareInterface; #[Group(Type::Daemon, 'frontend')] #[Service] #[Ingress('www.example.com')] final class FrontendVhost implements Vhost { private const string SERVER_NAME = 'frontend'; private const int LISTEN_PORT = 1337; public static function port(): int { return self::LISTEN_PORT; } public static function name(): string { return self::SERVER_NAME; } public static function webroot(): Webroot { return new NoWebroot(); } public static function maxConcurrentRequests(): null { return null; } /** @return iterable<MiddlewareInterface> */ public function middleware(): iterable { yield from []; } }
For a ready-made health and probe vhost, see mammatus/healthz-vhost (port 9666, Kubernetes probes, static files under public/).
HTTP route handlers
Handlers are plain PHP classes annotated with #[Vhost] and #[Route]. The collector (Collector::handler()) registers each matching public method that is not a constructor or destructor and has zero or one parameter. With one parameter, the type is a route payload DTO (FastRoute path segments map into it). Static and instance methods are both supported (Handler).
Home page handler (HomePageHandler.php):
#[Vhost('frontend')] #[Route(HttpMethod::GET, '/')] final readonly class HomePageHandler { public function handle(): ResponseInterface { return new Response(OK, ['Content-Type' => 'text/plain'], 'Hello World!'); } }
Route parameter payload (PingHandler.php and Ping.php):
#[Vhost('frontend')] #[Route(HttpMethod::GET, '/ping/{name}')] final readonly class PingHandler { public function handle(Ping $ping): ResponseInterface { return new Response(OK, ['Content-Type' => 'application/json'], '{}'); } }
Probe routes and other attributes are documented in mammatus/http-server-attributes.
Publishing vhosts from a Composer package
Set extra.mammatus.http.server.has-vhosts to true in composer.json so the plugin scans that package for Vhost implementations and attributed handlers (this package and healthz-vhost use the same flag):
"extra": { "mammatus": { "http": { "server": { "has-vhosts": true } } } }
Application code and every scanned package contribute handlers to the same generated servers keyed by vhost name.
Hacking this repository
See CONTRIBUTING.md. Run make install, then make contrib while iterating and make before opening a pull request. Example vhost and handlers live under etc/dev-app/.
License
The MIT License (MIT)
Copyright (c) 2026 Cees-Jan Kiewiet
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.