Устаревшее расширение mongo десериализовало, как документы, так и массивы BSON в качестве массивов PHP. Хотя с PHP массивами удобно работать, такое поведение было проблематичным, поскольку различные типы BSON могут десериализоваться до одного и того же значения PHP (например, {"0": "foo"} и ["foo"]) и будет невозможно вывести оригинальный тип BSON. По умолчанию текущий драйвер решает эту проблему, обеспечивая преобразование массивов и документов BSON в массивы и объекты PHP соответственно.
Для составных типов существует три типа данных:
относится только к документу верхнего уровня BSON
относится только к встроенным документам BSON
относится к массивам BSON
Помимо трех групповых типов, также можно настроить определенные поля в документе для сопоставления с типами данных, указанными ниже. В качестве примера, следующая карта типов позволяет сопоставить каждый встроенный документ в массиве "addresses" с классом Address, а каждое поле "city" в этих документах с встроенным адресом с классом City:
[ 'fieldPaths' => [ 'addresses.$' => 'MyProject\Address', 'addresses.$.city' => 'MyProject\City', ], ]
Каждый из этих трех типов данных, а также сопоставления для конкретных полей могут быть сопоставлены с различными типами PHP. Возможные значения сопоставления:
Массив BSON будет десериализован, как PHP array.
Документ BSON (корневой или внедренный) без свойства __pclass [1] становится объектом PHP stdClass, причем каждый ключ документа BSON устанавливается в качестве открытого свойства stdClass.
Документ BSON (корневой или встроенный) со свойством __pclass [1] становится объектом PHP имени класса, как это определено свойством __pclass.
Если указанный класс реализует интерфейс MMongoDB\BSON\Persistable, то свойства документа BSON, включая свойство __pclass, отправляются в виде ассоциативного массива в функцию MongoDB\BSON\Unserializable::bsonUnserialize() для инициализации свойств объекта.
Если названный класс не существует или не реализует интерфейс MongoDB\BSON\Persistable, будет использоваться stdClass, и каждый ключ документа BSON (включая __pclass) будет установлен, как открытое свойство stdClass.
Функциональность __pclass зависит от того, является ли свойство частью извлеченного документа MongoDB. Если вы используете проекцию при запросе документов, вам нужно включить поле __pclass в проекцию, чтобы эта функция работала.
Превращает массив BSON или документ BSON в массив PHP. Не будет специальной обработки свойства __pclass [1], но его можно установить, как элемент в возвращаемом массиве, если он присутствовал в документе BSON.
Превращает массив BSON или документ BSON в объект stdClass. Не будет специальной обработки свойства __pclass [1], но оно может быть установлено, как открытое свойство в возвращаемом объекте, если оно присутствовало в документе BSON.
Определяет имя класса, который должен десериализовать массив BSON или объект BSON. Для объектов BSON, которые содержат свойства __pclass, этот класс будет иметь приоритет.
Если названный класс не существует, не является конкретным (то есть является абстрактным или интерфейсом) или не реализует MongoDB\BSON\Unserializable, то выдается исключение MongoDB\Driver\Exception\InvalidArgumentException.
Если объект BSON имеет свойство __pclass, и этот класс существует и реализует MongoDB\BSON\Persistable, он заменит класс, представленный в карте типов.
Свойства документа BSON, включая свойство __pclass, если оно существует, будут отправлены в виде ассоциативного массива в функцию MongoDB\BSON\Unserializable::bsonUnserialize() для инициализации свойств объекта.
TypeMaps можно установить с помощью метода MongoDB\Driver\Cursor::setTypeMap() для объекта MongoDB\Driver\Cursor или аргумента $typeMap в MongoDB\BSON\toPHP(). Каждый из трех классов (root, document, и array) может быть задан индивидуально, в дополнение к типам полей.
Если значение на карте равно NULL, это означает то же самое, что и значение по умолчанию для этого элемента.
В этих примерах используются следующие классы:
который не реализует интерфейс
который реализует MongoDB\BSON\Unserializable
который реализует MongoDB\BSON\Persistable
который расширяет OurClass
Метод MongoDB\BSON\Unserializable::bsonUnserialize() класса YourClass, OurClass, OurClass выполняет итерацию по массиву и устанавливает свойства без изменений. Он также устанавливает для свойства $unserialized значение true:
<?php
function bsonUnserialize( array $map )
{
foreach ( $map as $k => $value )
{
$this->$k = $value;
}
$this->unserialized = true;
}
/* typemap: [] (все значения по умолчанию) */ { "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") }