Deserialization from BSON
The legacy mongo extension deserialized both BSON documents and arrays as PHP arrays. While PHP arrays are convenient to work with, this behavior was problematic because different BSON types could deserialize to the same PHP value (e.g. {"0": "foo"} and ["foo"]) and make it impossible to infer the original BSON type. By default, the current driver addresses this concern by ensuring that BSON arrays and documents are converted to PHP arrays and objects, respectively.
For compound types, there are three data types:
- root
-
refers to the top-level BSON document only
- document
-
refers to embedded BSON documents only
- array
-
refers to a BSON array
Besides the three collective types, it is also possible to configure specific fields in your document to map to the data types mentioned below. As an example, the following type map allows you to map each embedded document within an "addresses" array to an Address class and each "city" field within those embedded address documents to a City class:
[ 'fieldPaths' => [ 'addresses.$' => 'MyProject\Address', 'addresses.$.city' => 'MyProject\City', ], ]
Each of those three data types, as well as the field specific mappings, can be mapped against different PHP types. The possible mapping values are:
- not set or NULL (default)
-
-
A BSON array will be deserialized as a PHP array.
-
A BSON document (root or embedded) without a __pclass property [1] becomes a PHP stdClass object, with each BSON document key set as a public stdClass property.
-
A BSON document (root or embedded) with a __pclass property [1] becomes a PHP object of the class name as defined by the __pclass property.
If the named class implements the MongoDB\BSON\Persistable interface, then the properties of the BSON document, including the __pclass property, are sent as an associative array to the MongoDB\BSON\Unserializable::bsonUnserialize() function to initialise the object's properties.
If the named class does not exist or does not implement the MongoDB\BSON\Persistable interface, stdClass will be used and each BSON document key (including __pclass) will be set as a public stdClass property.
The __pclass functionality relies on the property being part of a retrieved MongoDB document. If you use a projection when querying for documents, you need to include the __pclass field in the projection for this functionality to work.
-
- "array"
-
Turns a BSON array or BSON document into a PHP array. There will be no special treatment of a __pclass property [1], but it may be set as an element in the returned array if it was present in the BSON document.
- "object" or "stdClass"
-
Turns a BSON array or BSON document into a stdClass object. There will be no special treatment of a __pclass property [1], but it may be set as a public property in the returned object if it was present in the BSON document.
- any other string
-
Defines the class name that the BSON array or BSON object should be deserialized as. For BSON objects that include __pclass properties, that class will take priority.
If the named class does not exist, is not concrete (i.e. it is abstract or an interface), or does not implement MongoDB\BSON\Unserializable then an MongoDB\Driver\Exception\InvalidArgumentException exception is thrown.
If the BSON object has a __pclass property and that class exists and implements MongoDB\BSON\Persistable it will supersede the class provided in the type map.
The properties of the BSON document, including the __pclass property if it exists, will be sent as an associative array to the MongoDB\BSON\Unserializable::bsonUnserialize() function to initialise the object's properties.
TypeMaps
TypeMaps can be set through the MongoDB\Driver\Cursor::setTypeMap() method on a MongoDB\Driver\Cursor object, or the $typeMap argument of MongoDB\BSON\toPHP(). Each of the three classes (root, document, and array) can be individually set, in addition to the field specific types.
If the value in the map is NULL, it means the same as the default value for that item.
Examples
These examples use the following classes:
- MyClass
-
which does not implement any interface
- YourClass
-
which implements MongoDB\BSON\Unserializable
- OurClass
-
which implements MongoDB\BSON\Persistable
- TheirClass
-
which extends OurClass
The MongoDB\BSON\Unserializable::bsonUnserialize() method of YourClass, OurClass, TheirClass iterate over the array and set the properties without modifications. It also sets the $unserialized property to true:
<?php
function bsonUnserialize( array $map )
{
foreach ( $map as $k => $value )
{
$this->$k = $value;
}
$this->unserialized = true;
}
/* typemap: [] (all defaults) */ { "foo": "yes", "bar" : false } -> stdClass { $foo => 'yes', $bar => false } { "foo": "no", "array" : [ 5, 6 ] } -> stdClass { $foo => 'no', $array => [ 5, 6 ] } { "foo": "no", "obj" : { "embedded" : 3.14 } } -> stdClass { $foo => 'no', $obj => stdClass { $embedded => 3.14 } } { "foo": "yes", "__pclass": "MyClass" } -> stdClass { $foo => 'yes', $__pclass => 'MyClass' } { "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "MyClass" } } -> stdClass { $foo => 'yes', $__pclass => Binary(0x80, 'MyClass') } { "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "YourClass") } -> stdClass { $foo => 'yes', $__pclass => Binary(0x80, 'YourClass') } { "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "OurClass") } -> OurClass { $foo => 'yes', $__pclass => Binary(0x80, 'OurClass'), $unserialized => true } { "foo": "yes", "__pclass": { "$type" : "44", "$binary" : "YourClass") } -> stdClass { $foo => 'yes', $__pclass => Binary(0x44, 'YourClass') }
/* typemap: [ "root" => "MissingClass" ] */ { "foo": "yes" } -> MongoDB\Driver\Exception\InvalidArgumentException("MissingClass does not exist") /* typemap: [ "root" => "MyClass" ] */ { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "MyClass" } } -> MongoDB\Driver\Exception\InvalidArgumentException("MyClass does not implement Unserializable interface") /* typemap: [ "root" => "MongoDB\BSON\Unserializable" ] */ { "foo": "yes" } -> MongoDB\Driver\Exception\InvalidArgumentException("Unserializable is not a concrete class") /* typemap: [ "root" => "YourClass" ] */ { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "MongoDB\BSON\Unserializable" } } -> YourClass { $foo => "yes", $__pclass => Binary(0x80, "MongoDB\BSON\Unserializable"), $unserialized => true } /* typemap: [ "root" => "YourClass" ] */ { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "MyClass" } } -> YourClass { $foo => "yes", $__pclass => Binary(0x80, "MyClass"), $unserialized => true } /* typemap: [ "root" => "YourClass" ] */ { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "OurClass" } } -> OurClass { $foo => "yes", $__pclass => Binary(0x80, "OurClass"), $unserialized => true } /* typemap: [ "root" => "YourClass" ] */ { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "TheirClass" } } -> TheirClass { $foo => "yes", $__pclass => Binary(0x80, "TheirClass"), $unserialized => true } /* typemap: [ "root" => "OurClass" ] */ { foo: "yes", "__pclass" : { "$type": "80", "$binary": "TheirClass" } } -> TheirClass { $foo => "yes", $__pclass => Binary(0x80, "TheirClass"), $unserialized => true }
/* typemap: [ 'root' => 'YourClass' ] */ { foo: "yes", "__pclass" : { "$type": "80", "$binary": "YourClass" } } -> YourClass { $foo => 'yes', $__pclass => Binary(0x80, 'YourClass'), $unserialized => true }
/* typemap: [ 'root' => 'array', 'document' => 'array' ] */ { "foo": "yes", "bar" : false } -> [ "foo" => "yes", "bar" => false ] { "foo": "no", "array" : [ 5, 6 ] } -> [ "foo" => "no", "array" => [ 5, 6 ] ] { "foo": "no", "obj" : { "embedded" : 3.14 } } -> [ "foo" => "no", "obj" => [ "embedded => 3.14 ] ] { "foo": "yes", "__pclass": "MyClass" } -> [ "foo" => "yes", "__pclass" => "MyClass" ] { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "MyClass" } } -> [ "foo" => "yes", "__pclass" => Binary(0x80, "MyClass") ] { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "OurClass" } } -> [ "foo" => "yes", "__pclass" => Binary(0x80, "OurClass") ]
/* typemap: [ 'root' => 'object', 'document' => 'object' ] */ { "foo": "yes", "__pclass": { "$type": "80", "$binary": "MyClass" } } -> stdClass { $foo => "yes", "__pclass" => Binary(0x80, "MyClass") }
Vertaling niet beschikbaar
De PHP-handleiding is nog niet in het Nederlands vertaald, dus het scherm is in het Engels. Als u wilt, kunt u het ook in het Frans of in het Duits raadplegen.
Als je de moed voelt, kun je je vertaling aanbieden ;-)
Nederlandse vertaling
U hebt gevraagd om deze site in het Nederlands te bezoeken. Voor nu wordt alleen de interface vertaald, maar nog niet alle inhoud.Als je me wilt helpen met vertalingen, is je bijdrage welkom. Het enige dat u hoeft te doen, is u op de site registreren en mij een bericht sturen waarin u wordt gevraagd om u toe te voegen aan de groep vertalers, zodat u de gewenste pagina's kunt vertalen. Een link onderaan elke vertaalde pagina geeft aan dat u de vertaler bent en heeft een link naar uw profiel.
Bij voorbaat dank.
Document heeft de 30/01/2003 gemaakt, de laatste keer de 26/10/2018 gewijzigd
Bron van het afgedrukte document:https://www.gaudry.be/nl/php-rf-mongodb.persistence.deserialization.html
De infobrol is een persoonlijke site waarvan de inhoud uitsluitend mijn verantwoordelijkheid is. De tekst is beschikbaar onder CreativeCommons-licentie (BY-NC-SA). Meer info op de gebruiksvoorwaarden en de auteur.
Referenties
Deze verwijzingen en links verwijzen naar documenten die geraadpleegd zijn tijdens het schrijven van deze pagina, of die aanvullende informatie kunnen geven, maar de auteurs van deze bronnen kunnen niet verantwoordelijk worden gehouden voor de inhoud van deze pagina.
De auteur Deze site is als enige verantwoordelijk voor de manier waarop de verschillende concepten, en de vrijheden die met de referentiewerken worden genomen, hier worden gepresenteerd. Vergeet niet dat u meerdere broninformatie moet doorgeven om het risico op fouten te verkleinen.