phpbotgram

BaseSession
in package

AbstractYes

Table of Contents

Properties

$api  : TelegramApiServer
$jsonDumps  : callable(mixed): string
$jsonLoads  : callable(string): mixed
$middleware  : RequestMiddlewareManager
$timeout  : float
$makeRequestRef  : Closure
Stable first-class-callable reference to makeRequest, captured once at construction. Re-creating `$this->makeRequest(...)` per invocation would produce a fresh Closure each time and bust RequestMiddlewareManager's chain cache (which keys by spl_object_id).

Methods

__construct()  : mixed
__invoke()  : mixed
Run $method through the session's middleware chain, terminating at makeRequest.
checkResponse()  : Response<string|int, mixed>
Maps Telegram error status codes to typed exceptions.
close()  : void
makeRequest()  : mixed
prepareValue()  : mixed
Resolves BotDefault sentinels, detaches InputFile to $files, encodes datetimes / enums / nested TelegramObject. Port of upstream session/base.py:179-250.
streamContent()  : ReadableStream
buildResponse()  : Response<string|int, mixed>
Build a typed Response from the wire payload.
deserializeResult()  : mixed
Recursively resolve `$returnsType` against `$raw`, returning a typed value the caller can hand directly to a `: <Type>` return slot.
deserializeUnionResult()  : mixed
Dispatch a `'union:<X>|<Y>[|<Z>]'` ReturnsType by inspecting the raw response value's PHP type and routing to the matching member.
extractResponseParams()  : array{0: ?int, 1: ?int}
Reads `retry_after` / `migrate_to_chat_id` from the typed `$response->parameters` when populated (Phase 2 codegen wires `buildResponse` to materialise it), falling back to the raw `$data['parameters']` shape that the Phase 1 stub leaves untouched.
rawMatchesUnionMember()  : bool
Runtime predicate for a single `'union:'` member token. Scalar member names match the matching PHP runtime type; everything else is taken to be a class name and matched against `is_array($raw)` (the wire representation of a typed Telegram object is always a JSON dictionary).
resolveResultClass()  : TelegramObject>
Map a `Method::ReturnsType` token to a `class-string<TelegramObject>`.

Properties

$jsonDumps read-only

public callable(mixed): string $jsonDumps

$jsonLoads read-only

public callable(string): mixed $jsonLoads

$makeRequestRef read-only

Stable first-class-callable reference to makeRequest, captured once at construction. Re-creating `$this->makeRequest(...)` per invocation would produce a fresh Closure each time and bust RequestMiddlewareManager's chain cache (which keys by spl_object_id).

private Closure $makeRequestRef

Methods

__construct()

public __construct([TelegramApiServer|null $api = null ][, null|callable(string): mixed $jsonLoads = null ][, null|callable(mixed): string $jsonDumps = null ][, float $timeout = 60.0 ]) : mixed
Parameters
$api : TelegramApiServer|null = null
$jsonLoads : null|callable(string): mixed = null

injectable JSON decoder (parity with aiogram's BaseSession.json_loads). Defaults to json_decode(..., true, JSON_THROW_ON_ERROR).

$jsonDumps : null|callable(mixed): string = null

injectable JSON encoder (parity with aiogram's BaseSession.json_dumps). Defaults to json_encode(..., JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE).

$timeout : float = 60.0

__invoke()

Run $method through the session's middleware chain, terminating at makeRequest.

public __invoke(Bot $bot, TelegramMethod<string|int, mixed> $method[, int|null $timeout = null ]) : mixed

Mirrors aiogram's BaseSession.__call__ (session/base.py:267-274). With an empty chain this is equivalent to calling makeRequest directly.

Parameters
$bot : Bot
$method : TelegramMethod<string|int, mixed>
$timeout : int|null = null

checkResponse()

Maps Telegram error status codes to typed exceptions.

public checkResponse(Bot $bot, TelegramMethod<string|int, mixed> $method, int $statusCode, string $content) : Response<string|int, mixed>
Parameters
$bot : Bot
$method : TelegramMethod<string|int, mixed>
$statusCode : int
$content : string
Return values
Response<string|int, mixed>

makeRequest()

public abstract makeRequest(Bot $bot, TelegramMethod<string|int, mixed> $method[, int|null $timeout = null ]) : mixed
Parameters
$bot : Bot
$method : TelegramMethod<string|int, mixed>
$timeout : int|null = null

prepareValue()

Resolves BotDefault sentinels, detaches InputFile to $files, encodes datetimes / enums / nested TelegramObject. Port of upstream session/base.py:179-250.

public prepareValue(mixed $value, Bot $bot, array<string, InputFile&$files[, bool $dumpsJson = true ]) : mixed
Parameters
$value : mixed
$bot : Bot
$files : array<string, InputFile>
$dumpsJson : bool = true

streamContent()

public abstract streamContent(string $url[, array<string, string> $headers = [] ][, int $timeout = 30 ][, int $chunkSize = 65536 ][, bool $raiseForStatus = true ]) : ReadableStream
Parameters
$url : string
$headers : array<string, string> = []
$timeout : int = 30
$chunkSize : int = 65536
$raiseForStatus : bool = true
Return values
ReadableStream

buildResponse()

Build a typed Response from the wire payload.

protected buildResponse(Bot $bot, TelegramMethod<string|int, mixed> $method, array<string|int, mixed> $data) : Response<string|int, mixed>

On the happy path (ok: true + a present result), the raw result is routed through deserializeResult() against the method's declared ReturnsType const so the caller sees a typed TelegramObject (or list thereof, or scalar). Error / non-ok payloads land here too — they surface to checkResponse() which maps the status code to the matching exception subclass without consulting $response->result.

Wired in by Cycle 3: prior to this commit, BaseSession returned result: null unconditionally — AmphpSession's success path would then throw a LogicException because the typed Method return contract couldn't be satisfied. The Method-class-side ReturnsType const is emitted by codegen precisely so this hook can do the right thing without per-method dispatch tables.

Parameters
$bot : Bot
$method : TelegramMethod<string|int, mixed>
$data : array<string|int, mixed>
Return values
Response<string|int, mixed>

deserializeResult()

Recursively resolve `$returnsType` against `$raw`, returning a typed value the caller can hand directly to a `: <Type>` return slot.

private deserializeResult(string $methodClass, string $returnsType, mixed $raw, Bot $bot) : mixed

Supports the four Method::ReturnsType shapes the codegen emits:

  • scalar names ('bool', 'int', 'string', 'float') — passthrough;
  • 'list:<X>' — recurse on each element with <X> as the inner type;
  • 'union:<X>|<Y>[|<Z>]' — polymorphic return; dispatch each member by the raw response value's PHP type (is_bool / is_int / is_string / is_array). The canonical case is Message|bool (seven Edit* / setGameScore methods);
  • class-string — Serializer::load($class, $raw, $bot).

Inner names for the list form are short names in the schema's Types\ namespace (the codegen never emits FQCNs for the inner element). They are prefixed before the class-string branch fires; if a future codegen change emits something else, the class-string branch handles FQCNs too.

Parameters
$methodClass : string
$returnsType : string
$raw : mixed
$bot : Bot

deserializeUnionResult()

Dispatch a `'union:<X>|<Y>[|<Z>]'` ReturnsType by inspecting the raw response value's PHP type and routing to the matching member.

private deserializeUnionResult(string $methodClass, string $unionSpec, mixed $raw, Bot $bot) : mixed

Each member is a short token: a scalar name (bool, int, string, float) for primitive returns, or a class short name for typed Types\<X> returns. Members are matched in declaration order with the first compatible runtime predicate winning:

  • boolis_bool($raw),
  • intis_int($raw),
  • stringis_string($raw),
  • floatis_float($raw),
  • class name — is_array($raw) (Telegram object payloads are JSON dictionaries).

The canonical use is 'union:Message|bool' (seven Edit* / setGameScore methods that return Message for chat-message targets and True for inline-message targets). Pre-fix the path threw ClientDecodeException on every successful inline-message edit because Serializer::load(Message::class, true) saw a non-array.

Parameters
$methodClass : string
$unionSpec : string
$raw : mixed
$bot : Bot

extractResponseParams()

Reads `retry_after` / `migrate_to_chat_id` from the typed `$response->parameters` when populated (Phase 2 codegen wires `buildResponse` to materialise it), falling back to the raw `$data['parameters']` shape that the Phase 1 stub leaves untouched.

private static extractResponseParams(Response<string|int, mixed> $response, array<string|int, mixed> $data) : array{0: ?int, 1: ?int}

Single extraction point so Phase 2 has one site to retire.

Parameters
$response : Response<string|int, mixed>
$data : array<string|int, mixed>
Return values
array{0: ?int, 1: ?int}

[retryAfter, migrateToChatId]

rawMatchesUnionMember()

Runtime predicate for a single `'union:'` member token. Scalar member names match the matching PHP runtime type; everything else is taken to be a class name and matched against `is_array($raw)` (the wire representation of a typed Telegram object is always a JSON dictionary).

private rawMatchesUnionMember(string $member, mixed $raw) : bool

bool runs the strict is_bool check so a true payload never accidentally dispatches as the class-name branch — the polymorphic Message|bool case depends on the bool member shadowing the class member whenever the raw value is a literal boolean.

Parameters
$member : string
$raw : mixed
Return values
bool

resolveResultClass()

Map a `Method::ReturnsType` token to a `class-string<TelegramObject>`.

private resolveResultClass(string $token) : TelegramObject>

Codegen emits either a FQCN (Foo::class constant materialises as the fully-qualified string) or a bare short name (the inner element of a list:X sentinel). Both shapes flow into here.

Parameters
$token : string
Return values
TelegramObject>
On this page

Search results