API Index — Namespaces, Packages, Reports, Indices
HostRouterMiddleware
in package
implements
MiddlewareInterface
Host-Router Middleware (nginx server_name virtual-host equivalent)
Dispatches the request to a per-host handler based on the Host: request
header. The handler is a normal callable returning any of ZealPHP's
supported return shapes (string body, PSR-7 Response, Generator,
array → JSON, int → status code).
nginx equivalent:
server { server_name a.com; location / { ... } }
server { server_name b.com; location / { ... } }
If no host matches and no '*' (catch-all) handler is registered, the
middleware passes through to the next handler. This lets you mix
host-routed and host-agnostic apps inside one ZealPHP instance:
$app->addMiddleware(new \ZealPHP\Middleware\HostRouterMiddleware([
'docs.example.com' => fn() => 'docs landing page',
'api.example.com' => fn() => ['status' => 'ok'],
'*.example.com' => fn() => 'subdomain fallback',
'www.*' => fn() => 'trailing-wildcard catch',
'~^admin\..+' => fn() => 'regex match',
'*' => fn() => 'default site',
]));
Host matching is case-insensitive and ignores port (example.com:8080
matches the rule example.com). IPv6 literals ([::1]:80) are parsed
correctly — the port separator is the : after the closing ].
Match precedence (nginx ngx_hash_find_combined order):
- Exact match
- Leading-wildcard
*.example.com - Trailing-wildcard
www.* - Regex
~^pattern(in registration order) - Catch-all
*
Host validation (nginx parity, only when HostRouterMiddleware is active):
- HTTP/1.1 with missing
Host→400 - Duplicate
Hostheaders →400 - Invalid
Hostcharacters (outside[a-zA-Z0-9:.\-_~!$&'()*+,;=%@[\]]) →400 - Trailing dot normalised:
example.com.→example.com
Table of Contents
Interfaces
- MiddlewareInterface
Properties
- $catchAll : callable|null
- $handlers : array<string, callable>
- $regexRules : array<int, array{pattern: string, handler: callable}>
- $trailingWildcards : array<int, array{host: string, handler: callable}>
- $wildcards : array<int, array{host: string, handler: callable}>
Methods
- __construct() : mixed
- process() : ResponseInterface
- coerceResponse() : ResponseInterface
- isValidHostHeader() : bool
- Validate a raw
Hostheader value (nginxngx_http_validate_hostparity). - matchHandler() : callable|null
- Match the normalised (lowercased, port-stripped) host against registered
rules in nginx precedence order:
1. Exact
2. Leading-wildcard (
*.example.com) 3. Trailing-wildcard (www.*) 4. Regex (~^pattern, registration order) 5. Catch-all (*) - stripPort() : string
- Strip the port from a
Hostheader value.
Properties
$catchAll
private
callable|null
$catchAll
$handlers
private
array<string, callable>
$handlers
normalised host => handler
$regexRules
private
array<int, array{pattern: string, handler: callable}>
$regexRules
regex rules in declaration order
$trailingWildcards
private
array<int, array{host: string, handler: callable}>
$trailingWildcards
trailing-wildcard rules (www.*) in declaration order
$wildcards
private
array<int, array{host: string, handler: callable}>
$wildcards
leading-wildcard rules (*.x) in declaration order
Methods
__construct()
public
__construct(array<string, mixed> $hosts) : mixed
Parameters
- $hosts : array<string, mixed>
-
host => callable, plus optional
'*'catch-all. Markedmixedat the type-level because PHP can't enforcecallableinside an array; each handler is validated at runtime.
process()
public
process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
Parameters
- $request : ServerRequestInterface
- $handler : RequestHandlerInterface
Return values
ResponseInterfacecoerceResponse()
private
coerceResponse(mixed $result) : ResponseInterface
Parameters
- $result : mixed
Return values
ResponseInterfaceisValidHostHeader()
Validate a raw Host header value (nginx ngx_http_validate_host parity).
private
isValidHostHeader(string $host) : bool
Allowed characters: a-zA-Z0-9 : . - _ ~ ! $ & ' ( ) * + , ; = % @ [ ]
Rejects NUL bytes, control characters, <, >, {, }, |, \, ^, `, space, and
consecutive dots (which nginx also rejects).
Parameters
- $host : string
Return values
boolmatchHandler()
Match the normalised (lowercased, port-stripped) host against registered
rules in nginx precedence order:
1. Exact
2. Leading-wildcard (*.example.com)
3. Trailing-wildcard (www.*)
4. Regex (~^pattern, registration order)
5. Catch-all (*)
private
matchHandler(string $host) : callable|null
Parameters
- $host : string
Return values
callable|nullstripPort()
Strip the port from a Host header value.
private
stripPort(string $host) : string
Handles:
example.com:8080 → example.com
[::1]:8080 → [::1]
[::1] → [::1]
::1 → ::1 (no brackets, no port)
Parameters
- $host : string