phpbotgram

MongoStorage extends BaseStorage
in package

FinalYes

MongoDB-backed FSM storage.

Mirrors aiogram.fsm.storage.mongo.MongoStorage (≈170 lines). State and data are stored as fields inside a single MongoDB document keyed by _id = keyBuilder->build($key) (no part suffix — one document per FSM context, unlike Redis which uses separate keys per part).

I/O model

The mongodb/mongodb userland library is synchronous (blocking I/O). Every blocking call is wrapped in Amp\async(fn) so the blocking work runs in a separate fiber and the parent fiber is suspended, not stalled. This mirrors the pattern established in BaseSession.

Dependency injection

The constructor accepts a MongoCollectionInterface — a tiny internal contract satisfied by MongoCollectionAdapter (which wraps the real \MongoDB\Collection) in production, and by lightweight anonymous-class mocks in unit tests. This decouples the storage from ext-mongodb at the type level, so the unit-test suite runs without the extension.

Factory methods

  • MongoStorage::fromUrl(string $url, ...) — builds a real \MongoDB\Client, wraps the selected collection in an adapter. Requires ext-mongodb.
  • MongoStorage::create(\MongoDB\Client $client, ...) — same but accepts a pre-built client (useful when TLS / auth options are complex).
  • MongoStorage::fromCollection(MongoCollectionInterface $col, ...) — primary injection point; used by unit tests.

Document structure

{ "_id": "<keyBuilder_output>", "state": "Group:name", "data": { ... } }

When state / data is cleared, $unset removes the field. If both fields are absent after the update the document is deleted to avoid accumulating empty records (upstream Python behaviour).

Tags
see
MongoCollectionInterface
MongoCollectionAdapter

Table of Contents

Properties

$collection  : MongoCollectionInterface
$keyBuilder  : KeyBuilder

Methods

__construct()  : mixed
close()  : void
Release resources.
create()  : self
Create a `MongoStorage` from an existing `\MongoDB\Client`.
fromCollection()  : self
Create a `MongoStorage` from a `MongoCollectionInterface` directly.
fromUrl()  : self
Create a `MongoStorage` from a MongoDB connection URI.
getData()  : array<string, mixed>
Retrieve the FSM data payload for the given key.
getState()  : null|string
Retrieve the FSM state for the given key.
getValue()  : mixed
Read a single key from the data map stored at `$storageKey`.
setData()  : void
Persist the FSM data payload for the given key.
setState()  : void
Persist the FSM state for the given key.
updateData()  : array<string, mixed>
Merge `$data` into the existing FSM data payload for `$key` atomically.
unsetField()  : void
Remove `$field` from the document identified by `$documentId` using `$unset`. If the document is empty after the update (or absent), the whole document is deleted to avoid accumulating empty records.

Properties

Methods

close()

Release resources.

public close() : void

\MongoDB\Client manages an internal connection pool and does not expose an explicit close() method. This is intentionally a no-op, matching upstream Python's self._client.close() which is also effectively a no-op in most deployments.

create()

Create a `MongoStorage` from an existing `\MongoDB\Client`.

public static create(Client $client[, string $database = 'phpbotgram_fsm' ][, string $collectionName = 'states_and_data' ][, null|KeyBuilder $keyBuilder = null ]) : self
Parameters
$client : Client

Pre-built MongoDB client.

$database : string = 'phpbotgram_fsm'

Database name.

$collectionName : string = 'states_and_data'

Collection name.

$keyBuilder : null|KeyBuilder = null

Optional key-builder override.

Return values
self

fromCollection()

Create a `MongoStorage` from a `MongoCollectionInterface` directly.

public static fromCollection(MongoCollectionInterface $collection[, null|KeyBuilder $keyBuilder = null ]) : self

This is the primary injection point used by unit tests.

Parameters
$collection : MongoCollectionInterface

Adapted (or mocked) collection.

$keyBuilder : null|KeyBuilder = null

Optional key-builder override.

Return values
self

fromUrl()

Create a `MongoStorage` from a MongoDB connection URI.

public static fromUrl(string $url[, array<string, mixed> $clientOptions = [] ][, array<string, mixed> $driverOptions = [] ][, string $database = 'phpbotgram_fsm' ][, string $collectionName = 'states_and_data' ][, null|KeyBuilder $keyBuilder = null ]) : self

Mirrors MongoStorage.from_url (upstream Python). Requires ext-mongodb.

Parameters
$url : string

MongoDB connection URI.

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

Options forwarded to \MongoDB\Client.

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

Driver options forwarded to \MongoDB\Client.

$database : string = 'phpbotgram_fsm'

Database name.

$collectionName : string = 'states_and_data'

Collection name.

$keyBuilder : null|KeyBuilder = null

Optional key-builder override.

Return values
self

getData()

Retrieve the FSM data payload for the given key.

public getData(StorageKey $key) : array<string, mixed>
Parameters
$key : StorageKey

Storage address.

Return values
array<string, mixed>

Current data map (empty array when no data stored).

getState()

Retrieve the FSM state for the given key.

public getState(StorageKey $key) : null|string
Parameters
$key : StorageKey

Storage address.

Return values
null|string

Stored state name, or null if none.

getValue()

Read a single key from the data map stored at `$storageKey`.

public getValue(StorageKey $storageKey, string $dictKey[, mixed $default = null ]) : mixed

Returns $default when the dict key is absent. PHP collapses the upstream @overload pattern into one method with a mixed $default = null parameter.

Parameters
$storageKey : StorageKey

Storage address.

$dictKey : string

Key within the data map.

$default : mixed = null

Value to return when $dictKey is not present.

Return values
mixed

The stored value, or $default.

Mirrors BaseStorage.get_value (base.py:151-168).

setData()

Persist the FSM data payload for the given key.

public setData(StorageKey $key, array<string, mixed> $data) : void

An empty array results in the data field being $unset. If the document becomes entirely empty afterward it is deleted.

Parameters
$key : StorageKey

Storage address.

$data : array<string, mixed>

Data map to store.

setState()

Persist the FSM state for the given key.

public setState(StorageKey $key[, null|State|string $state = null ]) : void
  • $state === null$unset the state field; if the document is now empty (no data field either), delete the document.
  • $state instanceof State → store $state->state().
  • $state is a plain string → store as-is.

Every blocking MongoDB call is wrapped in Amp\async() so the event loop is not stalled.

Parameters
$key : StorageKey

Storage address.

$state : null|State|string = null

New state value.

updateData()

Merge `$data` into the existing FSM data payload for `$key` atomically.

public updateData(StorageKey $key, array<string, mixed> $data) : array<string, mixed>

Unlike the default BaseStorage::updateData (read-merge-write, racy under concurrency), this override uses a single updateOne with dot-notation $set — matching upstream's atomic findOneAndUpdate($set: {data.field: value, ...}, upsert=True) pattern (aiogram/fsm/storage/mongo.py:133-146).

When $data is empty the operation is skipped and the current data is returned unchanged.

Parameters
$key : StorageKey

Storage address.

$data : array<string, mixed>

Partial data map to merge in.

Return values
array<string, mixed>

The merged data map as it now exists in the document.

unsetField()

Remove `$field` from the document identified by `$documentId` using `$unset`. If the document is empty after the update (or absent), the whole document is deleted to avoid accumulating empty records.

private unsetField(string $documentId, string $field) : void

Must be called from within an Amp\async() closure.

Parameters
$documentId : string
$field : string
On this page

Search results