Les documents BSON peuvent techniquement contenir des clés dupliquées car les documents sont stockés en tant qu'une liste de paire clé-valeur ; cependant, les applications devrait s'abstenir de générer des documents avec des clés dupliquées car le comportement du serveur et du pilote peut être indéfinie. Puisque les objets et tableaux PHP ne peuvent pas avoir de clés dupliquées, les données pourraient aussi être perdu lors du décodage d'un document BSON avec des clés dupliquées.
L'extension mongodb
désérialise les documents BSON
et les tableaux BSON en tant que tableaux PHP. Tant que les tableaux PHP sont
pratiques à utiliser, ce comportement était problématique car différents
types BSON pouvaient être désérialisés en la même valeur PHP (par exemple
{"0": "foo"}
et ["foo"]
) et rendait
impossible d'inférer le type BSON original. Par défaut, l'extension
mongodb
adresse cette préoccupation en s'assurant que les
tableaux BSON et les documents BSON sont convertis en tableaux et objets PHP,
respectivement.
Pour les types composés, il existe trois types de données :
réfère à un document BSON de niveau supérieur seulement
réfère à des documents BSON imbriqués seulement
réfère à un tableau BSON
A part les trois types collectifs, il est aussi possible de configurer des
champs spécifiques dans votre document pour mapper les types de données
mentionnés ci-dessous. Par exemple, le type de carte suivant vous permet de
mapper chaque document intégré dans un tableau "addresses"
à une classe Address et chaque
champ "city"
dans ces documents d'adresse intégrés à une
classe City:
[ 'fieldPaths' => [ 'addresses.$' => 'MyProject\Address', 'addresses.$.city' => 'MyProject\City', ], ]
Chacun de ces trois types de données, ainsi que les mappages spécifiques aux champs, peuvent être mappés contre différents types PHP. Les valeurs de mappage possibles sont:
Un tableau BSON sera désérialisé en un tableau PHP.
Un document BSON (racine ou imbriqué) sans propriété __pclass [1] devient un objet stdClass, avec chaque clé de document BSON définie comme une propriété de stdClass publique.
Un document BSON (racine ou imbriqué) avec une propriété __pclass devient un objet PHP de la classe nommée par la propriété __pclass.
Si la classe nommée implémente l'interface MongoDB\BSON\Persistable, alors les propriétés du document BSON, y compris la propriété __pclass, sont envoyées sous forme de tableau associatif à la fonction MongoDB\BSON\Unserializable::bsonUnserialize() pour initialiser les propriétés de l'objet.
Si la classe nommée n'existe pas ou n'implémente pas l'interface MongoDB\BSON\Persistable, stdClass sera utilisé et chaque clé de document BSON (y compris __pclass) sera définie comme une propriété publique de stdClass.
La fonctionnalité __pclass repose sur le fait que la propriété soit partie d'un document MongoDB récupéré. Si vous utilisez une » projection lors de la recherche de documents, vous devez inclure le champ __pclass dans la projection pour que cette fonctionnalité fonctionne.
"array"
Transforme un tableau BSON en un tableau PHP. Il n'y aura pas de traitement spécial d'une propriété __pclass [1] mais elle peut être définie comme un élément dans le tableau retourné si elle était présente dans le document BSON.
"object"
ou "stdClass"
Transforme un tableau BSON ou un document BSON en un objet stdClass. Il n'y aura pas de traitement spécial d'une propriété __pclass [1] mais elle peut être définie comme une propriété publique dans l'objet retourné si elle était présente dans le document BSON.
"bson"
Transforme un tableau BSON en un MongoDB\BSON\PackedArray et un document BSON en un MongoDB\BSON\Document, indépendamment du fait que le document BSON ait une propriété __pclass [1].
Note: La valeur
bson
n'est disponible que pour les trois types racines, et non dans les mappages spécifiques aux champs.
Définit le nom de la classe à laquelle le document BSON doit être désérialisé. Pour les documents BSON qui incluent des propriétés __pclass, cette classe prendra la priorité.
Si la classe nommée n'existe pas ou n'implémente pas l'interface MongoDB\BSON\Unserializable, une exception MongoDB\Driver\Exception\InvalidArgumentException est lancée.
Si l'objet BSON a une propriété __pclass et que cette classe existe et implémente MongoDB\BSON\Persistable, elle prendra le pas sur la classe fournie dans la carte de type.
Les propriétés du document BSON, y compris la propriété __pclass, seront envoyées sous forme de tableau associatif à la fonction MongoDB\BSON\Unserializable::bsonUnserialize() pour initialiser les propriétés de l'objet.
Les TypeMaps peuvent être définis via la méthode
MongoDB\Driver\Cursor::setTypeMap() sur un objet
MongoDB\Driver\Cursor, ou l'argument
$typeMap
de
MongoDB\BSON\toPHP(),
MongoDB\BSON\Document::toPHP(), et
MongoDB\BSON\PackedArray::toPHP(). Chacune des trois
classes (racine, document, et
array) peut être définie individuellement, en plus des
types spécifiques aux champs.
Si la valeur dans le TypeMap est NULL, cela signifie la même chose que la valeur par défaut pour cet élément.
Ces exemples utilisent les classes suivantes:
qui n'implémente aucune interface
qui implémente MongoDB\BSON\Unserializable
qui implémente MongoDB\BSON\Persistable
qui étends OurClass
La méthode MongoDB\BSON\Unserializable::bsonUnserialize()
de YourClass, OurClass, TheirClass itère sur le tableau et définit les
propriétés sans modifications. Elle ajoute aussi la
propriété $unserialized
à 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") }