HandlerObject
extends CallableObject
in package
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
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
$callback read-only
public
Closure
$callback
$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 onTelegramEventObserver. - $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.$kwargsis the input$kwargsplus the merged entries from each filter that returned an array (last-wins on key collision, matching Pythondict.update()).[false, $kwargs]— a filter rejected.$kwargsreflects 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'sif not checkbranch 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: arrayisVariadic()
Whether the callback declares a variadic tail (`...$rest`). When true, `prepareKwargs()` becomes a no-op pass-through.
public
isVariadic() : bool
Return values
boolparams()
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>