Alpha ZealPHP is early-stage and under active development. APIs may change between minor versions until v1.0. Feedback and bug reports welcome on GitHub.
API Index — Namespaces, Packages, Reports, Indices

IpAccessMiddleware
in package
implements MiddlewareInterface

IP Access Middleware

Allow/deny request access by client IP. Supports literal IPv4/IPv6 and CIDR notation (10.0.0.0/8, 2001:db8::/32). The wildcard '*' matches any IP — useful to express "allow everyone except deny list" or "deny by default".

Apache 2.2 equivalent (legacy):

Order Deny,Allow
Deny from all
Allow from 10.0.0.0/8 127.0.0.1

Apache 2.4+ / nginx equivalent:

Require ip 10.0.0.0/8 127.0.0.1                  # Apache 2.4+
allow 10.0.0.0/8; allow 127.0.0.1; deny all;     # nginx

Resolution rules:

  1. If deny matches the IP → 403 (deny wins ties)
  2. Else if allow is non-empty and doesn't match → 403
  3. Else → pass through

So ['allow' => ['10.0.0.0/8'], 'deny' => []] is "allow-list only"; ['allow' => ['*'], 'deny' => ['1.2.3.4']] is "deny-list only"; ['allow' => ['10.0.0.0/8'], 'deny' => ['10.1.2.3']] is "allow the subnet except this specific host".

Note on proxied apps: reads $g->server['REMOTE_ADDR']. If you're behind Traefik/Caddy/nginx, that's the proxy IP, not the real client. Use App::clientIp() (once available) and pass the value into a custom middleware, or terminate the trust at the proxy layer.

Usage in app.php:

// Allow only office network and CI
$app->addMiddleware(new \ZealPHP\Middleware\IpAccessMiddleware([
    'allow' => ['203.0.113.0/24', '198.51.100.42'],
    'deny'  => [],
]));

// Block a specific abuser, allow the rest
$app->addMiddleware(new \ZealPHP\Middleware\IpAccessMiddleware([
    'allow' => ['*'],
    'deny'  => ['1.2.3.4'],
]));

Table of Contents

Interfaces

MiddlewareInterface

Properties

$allow  : array<string|int, string>
$deny  : array<string|int, string>

Methods

__construct()  : mixed
process()  : ResponseInterface
cidrMatch()  : bool
clientIp()  : string
forbidden()  : ResponseInterface
matchesAny()  : bool

Properties

Methods

__construct()

public __construct([array{allow?: string[], deny?: string[]} $config = [] ]) : mixed
Parameters
$config : array{allow?: string[], deny?: string[]} = []

process()

public process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
Parameters
$request : ServerRequestInterface
$handler : RequestHandlerInterface
Return values
ResponseInterface

cidrMatch()

private cidrMatch(string $ip, string $cidr) : bool
Parameters
$ip : string
$cidr : string
Return values
bool

clientIp()

private clientIp(ServerRequestInterface $request) : string
Parameters
$request : ServerRequestInterface
Return values
string

forbidden()

private forbidden() : ResponseInterface
Return values
ResponseInterface

matchesAny()

private matchesAny(string $ip, array<string|int, string> $rules) : bool
Parameters
$ip : string
$rules : array<string|int, string>
Return values
bool
On this page