Signatur
Beschreibung
Das Interface MongoDB\BSON\Unserializable ermöglicht es, eigene PHP-Klassen so zu gestalten, dass sie beim Lesen von MongoDB-Dokumenten automatisch als Instanzen dieser Klassen wiederhergestellt werden. Implementiert eine Klasse dieses Interface, wird die Methode bsonUnserialize() aufgerufen, sobald der MongoDB-Treiber ein BSON-Dokument in ein PHP-Objekt umwandelt.
Die Methode bsonUnserialize() erhält ein Array oder Objekt mit den Feldern des BSON-Dokuments und ist dafür zuständig, den internen Zustand des Objekts zu befüllen. Auf diese Weise lässt sich das Domain-Modell einer Anwendung direkt mit der Datenbankschicht verbinden, ohne manuelle Mapping-Logik schreiben zu müssen.
Damit der MongoDB-Treiber weiß, welche PHP-Klasse für ein Dokument verwendet werden soll, muss in der TypeMap-Option der jeweilige Klassenname angegeben werden, oder die Klasse muss als __pclass-Feld im Dokument registriert sein (in Kombination mit MongoDB\BSON\Persistable). Häufig wird Unserializable gemeinsam mit MongoDB\BSON\Serializable implementiert, um einen vollständigen Datenbankzyklus abzubilden.
Dieses Interface eignet sich besonders für Value-Objects, Entitäten oder DTOs, bei denen eine strikte Kontrolle über die Deserialisierung erforderlich ist, etwa wenn Felder validiert, transformiert oder auf private Eigenschaften abgebildet werden müssen.
Beispiele
Eigene Klasse aus MongoDB-Dokument deserialisieren
<?php
use MongoDB\BSON\Unserializable;
class Adresse implements Unserializable
{
private string $strasse;
private string $stadt;
private string $plz;
public function bsonUnserialize(array $data): void
{
$this->strasse = $data['strasse'] ?? '';
$this->stadt = $data['stadt'] ?? '';
$this->plz = $data['plz'] ?? '';
}
public function getStrasse(): string { return $this->strasse; }
public function getStadt(): string { return $this->stadt; }
public function getPlz(): string { return $this->plz; }
}
// TypeMap beim Datenbankzugriff konfigurieren:
$client = new MongoDB\Client();
$collection = $client->meindb->adressen;
$cursor = $collection->find(
[],
['typeMap' => ['root' => Adresse::class, 'document' => 'array']]
);
foreach ($cursor as $adresse) {
echo $adresse->getStadt() . PHP_EOL;
}
Gemeinsame Implementierung mit Serializable (Persistable-Muster)
<?php
use MongoDB\BSON\Unserializable;
use MongoDB\BSON\Serializable;
use MongoDB\BSON\ObjectId;
class Produkt implements Serializable, Unserializable
{
private ?ObjectId $id;
private string $name;
private float $preis;
public function __construct(string $name, float $preis, ?ObjectId $id = null)
{
$this->name = $name;
$this->preis = $preis;
$this->id = $id;
}
// Wird beim Speichern in MongoDB aufgerufen
public function bsonSerialize(): array
{
$data = ['name' => $this->name, 'preis' => $this->preis];
if ($this->id !== null) {
$data['_id'] = $this->id;
}
return $data;
}
// Wird beim Lesen aus MongoDB aufgerufen
public function bsonUnserialize(array $data): void
{
$this->id = $data['_id'] ?? null;
$this->name = $data['name'] ?? '';
$this->preis = (float)($data['preis'] ?? 0.0);
}
public function getName(): string { return $this->name; }
public function getPreis(): float { return $this->preis; }
}
$client = new MongoDB\Client();
$collection = $client->shop->produkte;
// Speichern
$produkt = new Produkt('Laptop', 999.99);
$collection->insertOne($produkt);
// Lesen mit TypeMap
$gefunden = $collection->findOne(
['name' => 'Laptop'],
['typeMap' => ['root' => Produkt::class, 'document' => 'array']]
);
echo $gefunden->getName() . ': ' . $gefunden->getPreis() . ' EUR' . PHP_EOL;
// Wichtig · Fallstricke
Pflichtmethode: Implementierende Klassen müssen zwingend die Methode public function bsonUnserialize(array $data): void bereitstellen. Fehlt sie, wirft PHP einen fatalen Fehler.
Konstruktor wird nicht aufgerufen: Beim Deserialisieren über bsonUnserialize() wird der Konstruktor der Klasse nicht automatisch aufgerufen. Initialisierungslogik, die normalerweise im Konstruktor steht, muss bei Bedarf explizit in bsonUnserialize() wiederholt oder ausgelagert werden.
TypeMap erforderlich: Ohne eine passende typeMap-Konfiguration wird das Dokument standardmäßig als stdClass oder Array zurückgegeben. Die Klasse muss explizit als Zieltyp angegeben werden, sofern nicht MongoDB\BSON\Persistable mit __pclass verwendet wird.
Sicherheit: Die Daten in $data stammen direkt aus der Datenbank. Eine Validierung und Typprüfung der eingehenden Felder in bsonUnserialize() ist empfehlenswert, um unerwartete Datenstrukturen oder fehlende Felder sicher zu behandeln.