Start · Sprachen · PHP · Referenz · MongoDB\BSON\Unserializable

MongoDB\BSON\Unserializable

Interface

Interface für Klassen, die aus BSON-Daten deserialisiert werden können und dabei die Kontrolle über den Wiederherstellungsprozess übernehmen.

seit PHP 1.0.0 Kategorie: db

Signatur

interface MongoDB\BSON\Unserializable

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;
Laptop: 999.99 EUR

// 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.