Signatur
Beschreibung
MongoDB\BSON\Serializable ist ein Interface aus dem MongoDB PHP-Treiber (Erweiterung mongodb). Es ermöglicht eigenen PHP-Klassen, die Kontrolle darüber zu übernehmen, wie ihre Instanzen beim Schreiben in eine MongoDB-Datenbank als BSON-Dokument serialisiert werden. Klassen, die dieses Interface implementieren, müssen die Methode bsonSerialize() definieren.
Die Methode bsonSerialize() wird automatisch vom Treiber aufgerufen, sobald ein Objekt der Klasse als BSON-Wert kodiert wird – beispielsweise beim Einfügen, Aktualisieren oder in Abfragebedingungen. Der Rückgabewert von bsonSerialize() muss ein array oder ein stdClass-Objekt (bzw. ein Objekt, das MongoDB\BSON\Document oder MongoDB\BSON\PackedArray ist) sein, das die zu speichernden Felder und Werte enthält.
Dieses Interface eignet sich besonders für Value-Objects, Domain-Entitäten und andere fachliche Modelle, bei denen man die BSON-Repräsentation exakt steuern möchte – etwa um interne PHP-Properties von der gespeicherten Struktur zu entkoppeln oder Typinformationen gezielt wegzulassen bzw. hinzuzufügen.
In Kombination mit MongoDB\BSON\Unserializable lässt sich ein vollständiger, symmetrischer Serialisierungs-/Deserialisierungszyklus abbilden. Der Treiber ruft beim Lesen aus der Datenbank dann die Methode bsonUnserialize() auf, um das Objekt aus dem BSON-Dokument wiederherzustellen.
Beispiele
Einfaches Value-Object mit benutzerdefinierter BSON-Serialisierung
<?php
use MongoDB\BSON\Serializable;
use MongoDB\BSON\ObjectId;
class Money implements Serializable
{
public function __construct(
private int $amount,
private string $currency
) {}
public function bsonSerialize(): array
{
return [
'amount' => $this->amount,
'currency' => $this->currency,
];
}
}
$price = new Money(1999, 'EUR');
// Beispielhaftes Einfügen in eine MongoDB-Collection:
// $collection->insertOne(['price' => $price]);
// => { "price": { "amount": 1999, "currency": "EUR" } }
// Manuell BSON erzeugen (zur Demonstration):
$bson = MongoDB\BSON\Document::fromPHP(['price' => $price]);
echo $bson->toRelaxedExtendedJSON();
Kombinierter Serialisierungs- und Deserialisierungszyklus
<?php
use MongoDB\BSON\Serializable;
use MongoDB\BSON\Unserializable;
class GeoPoint implements Serializable, Unserializable
{
public float $lat;
public float $lng;
public function __construct(float $lat, float $lng)
{
$this->lat = $lat;
$this->lng = $lng;
}
// Wird beim Schreiben nach MongoDB aufgerufen
public function bsonSerialize(): array
{
return [
'type' => 'Point',
'coordinates' => [$this->lng, $this->lat],
];
}
// Wird beim Lesen aus MongoDB aufgerufen
public function bsonUnserialize(array $data): void
{
$this->lng = $data['coordinates'][0];
$this->lat = $data['coordinates'][1];
}
}
$point = new GeoPoint(52.5200, 13.4050);
$doc = MongoDB\BSON\Document::fromPHP(['location' => $point]);
$back = $doc->toPHP([
'fieldPaths' => [
'location' => GeoPoint::class,
],
]);
echo get_class($back->location) . "\n";
echo $back->location->lat . ", " . $back->location->lng . "\n";
// Wichtig · Fallstricke
Rückgabetyp von bsonSerialize(): Der Rückgabewert muss ein array, ein stdClass-Objekt oder ab Treiber-Version 1.16 ein MongoDB\BSON\Document- bzw. MongoDB\BSON\PackedArray-Objekt sein. Andere Typen führen zu einer MongoDB\Driver\Exception\UnexpectedValueException.
Klassen-Map beachten: Damit der Treiber beim Lesen das richtige Objekt wiederherstellt, muss die Klasse zusätzlich MongoDB\BSON\Unserializable implementieren und in der sogenannten Type Map (Lese-Option typeMap) korrekt registriert sein.
Zirkuläre Referenzen in den zu serialisierenden Daten können zu Endlosrekursionen führen – hier ist Vorsicht geboten.