phpbotgram

HandlerObject extends CallableObject
in package

FinalYes

Wraps a handler callback together with its filter chain and metadata flags.

Mirrors upstream aiogram.dispatcher.event.handler.HandlerObject.

The router stores one of these per registered handler. At dispatch time it calls check() first; only if every filter votes "accept" does the handler itself run (via the inherited CallableObject::call()). The kwargs cascade described in FilterObject flows entirely through check() — see the method docblock for the exact rejection ladder.

The flags field is empty by default. Phase 3 Task 3.7 (Flags subsystem) lands the higher-level decorators that populate it from attribute-style metadata (#[Flag('admin_only')] etc.); HandlerObject itself just stores whatever the caller hands in.

Table of Contents

Properties

$callback  : Closure
$filters  : array<string|int, mixed>
$flags  : array<string|int, mixed>

Methods

__construct()  : mixed
call()  : mixed
Invoke the underlying closure. Positional `$args` are forwarded as-is; `$kwargs` is filtered via `prepareKwargs()` so a closure declaring only `$a` won't choke on an extra `bot:` kwarg the dispatcher injected.
check()  : array{0: bool, 1: array}
Run every filter in registration order against the supplied `$args` / `$kwargs`, accumulating kwargs from associative-array returns. Stops on the first rejection (any falsy result — `false`, `null`, `0`, `''`, `[]`).
isVariadic()  : bool
Whether the callback declares a variadic tail (`...$rest`). When true, `prepareKwargs()` becomes a no-op pass-through.
params()  : array<int, string>
Names of the declared (non-variadic) parameters in source order. The variadic tail, if any, is reported separately via `isVariadic()`.
prepareKwargs()  : array<string, mixed>
Filter `$kwargs` down to the keys the closure actually declares. When the closure has a variadic tail, every kwarg passes through untouched.

Properties

$filters read-only

public array<string|int, mixed> $filters = []

$flags read-only

public array<string|int, mixed> $flags = []

Methods

__construct()

public __construct(Closure $callback[, array<int, FilterObject$filters = [] ][, array<string, mixed> $flags = [] ]) : mixed
Parameters
$callback : Closure

The handler callable invoked once all filters accept. Receives the dispatcher's kwargs filtered through prepareKwargs() plus any entries injected by filter returns.

$filters : array<int, FilterObject> = []

Filters evaluated left-to-right by check(). An empty list means "always accept" — useful for catch-all handlers and for the root filters slot on TelegramEventObserver.

$flags : array<string, mixed> = []

Metadata flags attached to this handler. Stored verbatim and exposed read-only; middleware / introspection consumers read it. Phase 3 Task 3.7 will define the well-known keys.

call()

Invoke the underlying closure. Positional `$args` are forwarded as-is; `$kwargs` is filtered via `prepareKwargs()` so a closure declaring only `$a` won't choke on an extra `bot:` kwarg the dispatcher injected.

public call([array<int, mixed> $args = [] ][, array<string, mixed> $kwargs = [] ]) : mixed

Relies on PHP 8.1+ named-argument unpacking: ($cb)(...$args, ...$kwargs) forwards the integer-keyed entries positionally and the string-keyed entries as named arguments.

Exceptions raised by the callback propagate unchanged — no try/catch, matching upstream.

Parameters
$args : array<int, mixed> = []
$kwargs : array<string, mixed> = []

check()

Run every filter in registration order against the supplied `$args` / `$kwargs`, accumulating kwargs from associative-array returns. Stops on the first rejection (any falsy result — `false`, `null`, `0`, `''`, `[]`).

public check([array<int, mixed> $args = [] ][, array<string, mixed> $kwargs = [] ]) : array{0: bool, 1: array}

Returns a two-element tuple:

  • [true, $kwargs] — every filter accepted. $kwargs is the input $kwargs plus the merged entries from each filter that returned an array (last-wins on key collision, matching Python dict.update()).
  • [false, $kwargs] — a filter rejected. $kwargs reflects the merges that happened before the rejecting filter (later filters never run); the rejecting filter's own return value is discarded regardless of shape because upstream's if not check branch returns without merging.

Positional $args flow through every filter unchanged — they hold the Telegram event payload in production. Falsy semantics deliberately match Python's if not check: an empty array, an empty string, zero, or null all vote "reject" the same as a literal false.

Parameters
$args : array<int, mixed> = []
$kwargs : array<string, mixed> = []
Return values
array{0: bool, 1: array}

isVariadic()

Whether the callback declares a variadic tail (`...$rest`). When true, `prepareKwargs()` becomes a no-op pass-through.

public isVariadic() : bool
Return values
bool

params()

Names of the declared (non-variadic) parameters in source order. The variadic tail, if any, is reported separately via `isVariadic()`.

public params() : array<int, string>
Return values
array<int, string>

prepareKwargs()

Filter `$kwargs` down to the keys the closure actually declares. When the closure has a variadic tail, every kwarg passes through untouched.

public prepareKwargs(array<string, mixed> $kwargs) : array<string, mixed>
Parameters
$kwargs : array<string, mixed>
Return values
array<string, mixed>
On this page

Search results