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

RefererMiddleware
in package
implements MiddlewareInterface

Referer Middleware — nginx valid_referers / $invalid_referer parity.

Hotlink protection: refuses requests whose Referer header isn't in the allowed set with 403 Forbidden (the canonical if ($invalid_referer) { return 403; } pattern). Like nginx, this guards against casual mass-linking, not a determined attacker (Referer is trivially forged).

Allowed-referer specs mirror nginx:

  • allowNone (nginx none) — a missing Referer is allowed (default true)
  • allowBlocked (nginx blocked) — a Referer not starting with http(s):// is allowed (proxy-stripped) (default true)
  • host string — exact host, or wildcard *.example.com / example.*, with an optional URI prefix (example.org/galleries/); port is ignored
  • regex — prefixed with ~, matched case-insensitively (nginx NGX_REGEX_CASELESS parity) against the text after the scheme; malformed patterns are treated as misconfigurations — logged and the spec is skipped (fail-closed)
  • server_names token — pass serverNames: ['myapp.example.com'] to auto-allow requests originating from your own host(s); mirrors nginx server_names token (which auto-populates from the virtual host's server_name directives)

NOTE on empty-specs behaviour: unlike nginx (which with no valid_referers directive passes ALL requests), an empty $referers array here means no host/regex spec is in the allow-list, so any http(s):// Referer is blocked. This is intentional for a middleware (opt-in allow-listing); use allowNone and allowBlocked to tune the none/blocked token behaviour.

Usage in app.php:

$app->addMiddleware(new \ZealPHP\Middleware\RefererMiddleware(
    ['example.com', '*.example.com', '~\.google\.'],
    serverNames: ['myapp.example.com'],
));

Table of Contents

Interfaces

MiddlewareInterface

Properties

$allowBlocked  : bool
$allowNone  : bool
$serverNames  : array<string|int, mixed>
$specs  : array<int, string>

Methods

__construct()  : mixed
process()  : ResponseInterface
hostMatches()  : bool
isInvalid()  : bool
Mirror nginx's $invalid_referer: true ⇒ block.
matchSpec()  : bool

Properties

Methods

__construct()

public __construct(array<int, string> $referers[, bool $allowNone = true ][, bool $allowBlocked = true ][, array<int, string> $serverNames = [] ]) : mixed
Parameters
$referers : array<int, string>

Allowed host/wildcard/regex specs.

$allowNone : bool = true
$allowBlocked : bool = true
$serverNames : array<int, string> = []

Own host(s) to auto-allow (nginx server_names token).

process()

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

hostMatches()

private hostMatches(string $spec, string $host) : bool
Parameters
$spec : string
$host : string
Return values
bool

isInvalid()

Mirror nginx's $invalid_referer: true ⇒ block.

private isInvalid(string $referer) : bool
Parameters
$referer : string
Return values
bool

matchSpec()

private matchSpec(string $spec, string $host, string $path, string $afterScheme) : bool
Parameters
$spec : string
$host : string
$path : string
$afterScheme : string
Return values
bool
On this page