PHP 7.4.0RC2 Released!

Deserialización desde BSON

Para tipos compuestos, existen tres tipos de datos:

root

se refiere al documento BSON de más alto nivel solamente

document

se refiere a docuemtnos BSON embebidos solamente

array

se refiere a un array BSON

Cada uno de estos tres tipos de datos se pueden hacer corresponder con diferentes tipos de PHP. Los posibles valores de correspondencia son:

no establecido o NULL (es el predeterminado)

  • Un array BSON será deserializado como un array de PHP.

  • Un documento BSON (raíz o embebido) sin una propiedad __pclass [1] se convierte en un objeto stdClass de PHP, con cada clave de documento BSON establecida a propiedad stdClass pública.

  • Un documento BSON (raíz o embebido) con una propiedad __pclass [1] se convierte en un objeto de PHP del nombre de la clase definida por la propiedad __pclass.

    Si la clase con nombre implementa la intefaz MongoDB\BSON\Persistable, las propiedades del documento BSON, incluyendo la propiedad __pclass, son enviadas como un array asociativo a la función bsonUnserialize() para inicializar la propiedades del objeto.

    Si la clase con nombre no existe o no implementa la interfaz MongoDB\BSON\Persistable, se empleará stdClass y cada clave del documento BSON (incluyendo __pclass) será establecida a una propiedad stdClass pública.

"array"

Convierte un array BSON o documento BSON en un array de PHP. No habrá ningún tratamiento especial de una propiedad __pclass [1], aunque se podría establecer como un elemento del array devuelto si estaba presente el el documento BSON.

"object" o "stdClass"

Convierte un array BSON o documento BSON a un objeto stdClass. No habrá ningún tratamiento especial de una propiedad __pclass [1], aunque se podría establecer como propiedad pública del objeto devuelto si estaba presente en el documento BSON.

cualquier otro string

Define el nombre de la clase a la que debe ser deserializado el array BSON u objeto BSON. Para objetos BSON que incluyan propiedades __pclass, esta clase tomará prioridad.

Si la clase citada no existe, no es concreta (esto es, es abstracta o es una interfaz), o no implementa MongoDB\BSON\Unserializable, se lanzará una excepción MongoDB\Driver\Exception\InvalidArgumentException.

Si el objeto BSON posee una propiedad __pclass y esa clase existe e implementa MongoDB\BSON\Persistable, sustituirá a la clase proporcionada en el mapa de tipo.

Las propiedades del documento BSON, incluyendo la propiedad __pclass si existiera, será enviada como un array asociativo a la función bsonUnserialize() para inicializar las propiedades del objeto.

TypeMaps

TypeMaps se puede establecer a través del método MongoDB\Driver\Cursor::setTypeMap() en un objeto MongoDB\Driver\Cursor o del argumento $typeMap de MongoDB\BSON\toPHP(). Cada una de las tres clases (root, document and array) se pueden establecer individualmente.

Si el valor del mapa es NULL, significa lo mismo que el valor predeterminado para ese elemento.

Ejemplo

Estos ejemplos utilizan las siguientes clases:

MiClase

la cual no implementa ninguna interfaz

TuClase

que implementa MongoDB\BSON\Unserializable

NuestraClase

que implementa MongoDB\BSON\Persistable

SuClase

que extiende NuestraClase

El método bsonUnserialize() de TuClase, NuestraClase, SuClase recorre el array y establece las propiedades sin modificaciones. También establece la propiedad $no_serializada a 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") }

add a note add a note

User Contributed Notes 1 note

up
1
Miguel
1 year ago
Make sure you include the field "__pclass" to the projection if you want the ODM to automatically call the bsonUnserialize of the class.

If you don't get that field in the query, the ODM will never know which class to call, so you'll have to specify it with the "typemap" variable.
To Top