Сериализация в BSON
Массивы
Если массив является упакованным массивом - то есть ключи начинаются с 0 и являются последовательными без пробелов: массив BSON.
Если массив не упакован - то есть имеет ассоциативные (строковые) ключи, ключи не начинаются с 0 или при наличии пробелов:: объект BSON
Документ верхнего уровня (корневой), всегда сериализуется, как документ BSON.
Примеры
Сериализация, как массив BSON:
[ 8, 5, 2, 3 ] => [ 8, 5, 2, 3 ] [ 0 => 4, 1 => 9 ] => [ 4, 9 ]
Сериализация, как документ BSON:
[ 0 => 1, 2 => 8, 3 => 12 ] => { "0" : 1, "2" : 8, "3" : 12 } [ "foo" => 42 ] => { "foo" : 42 } [ 1 => 9, 0 => 10 ] => { "1" : 9, "0" : 10 }
Обратите внимание, что пять примеров являются выдержками из полного документа и представляют только одно значение внутри документа.
Объекты
Если объект принадлежит к классу stdClass, сериализуйте, как документ BSON.
Если объект является поддерживаемым классом, который реализует MongoDB\BSON\Type, то используйте логику сериализации BSON для этого конкретного типа. Экземпляры MongoDB\BSON\Type (исключая MongoDB\BSON\Serializable можно сериализовать только, как значение поля документа. Попытка сериализации такого объекта в качестве корневого документа приведет к выбросу MongoDB\Driver\Exception\UnexpectedValueException
Если объект неизвестного класса реализует интерфейс MongoDB\BSON\Type, выдается исключение MongoDB\Driver\Exception\UnexpectedValueException
Если объект относится к какому-либо другому классу, без реализации какого-либо специального интерфейса, сериализуйте, как документ BSON. Оставляйте только public свойства и игнорируйте protected и private свойства.
Если объект принадлежит к классу, который реализует интерфейс MongoDB\BSON\Serializable, вызовите MongoDB\BSON\Serializable::bsonSerialize() и используйте возвращенный массив или stdClass для сериализации в качестве документа BSON или массива. Тип BSON будет определяться следующим:
-
Корневые документы должны быть сериализованы, как документ BSON.
-
MongoDB\BSON\Persistable объекты должны быть сериализованы, как документ BSON.
-
Если MongoDB\BSON\Serializable::bsonSerialize() возвращает упакованный массив, сериализуйте его, как массив BSON.
-
Если MongoDB\BSON\Serializable::bsonSerialize() возвращает неупакованный массив или stdClass, сериализуйте, как документ BSON.
-
Если MongoDB\BSON\Serializable::bsonSerialize() не вернул массив или stdClass, выдаст исключение MongoDB\Driver\Exception\UnexpectedValueException.
Если объект принадлежит к классу, который реализует интерфейс
MongoDB\BSON\Persistable (что
подразумевает MongoDB\BSON\Serializable), получите
свойства аналогично предыдущим абзацам, но
также добавьте дополнительное свойство
__pclass в качестве Binary значения с подтипом
0x80
и данными, содержащими полное имя класса
сериализуемого объекта.
Свойство __pclass добавляется в массив или объект, возвращаемый MongoDB\BSON\Serializable::bsonSerialize(), что означает, что оно будет перезаписывать любой ключ/свойство __pclass в возвращаемом значении MongoDB\BSON\Serializable::bsonSerialize(). Если вы хотите избежать такого поведения и установить собственное значение __pclass, вы не должны реализовывать MongoDB\BSON\Persistable и вместо этого должны реализовывать MongoDB\BSON\Serializable напрямую.
Примеры
<?php
class stdClass {
public $foo = 42;
} // => { "foo" : 42 }
class MyClass {
public $foo = 42;
protected $prot = "wine";
private $fpr = "cheese";
} // => { "foo" : 42 }
class AnotherClass1 implements MongoDB\BSON\Serializable {
public $foo = 42;
protected $prot = "wine";
private $fpr = "cheese";
function bsonSerialize() {
return [ 'foo' => $this->foo, 'prot' => $this->prot ];
}
} // => { "foo" : 42, "prot" : "wine" }
class AnotherClass2 implements MongoDB\BSON\Serializable {
public $foo = 42;
function bsonSerialize() {
return $this;
}
} // => MongoDB\Driver\Exception\UnexpectedValueException("bsonSerialize() did not return an array or stdClass")
class AnotherClass3 implements MongoDB\BSON\Serializable {
private $elements = [ 'foo', 'bar' ];
function bsonSerialize() {
return $this->elements;
}
} // => { "0" : "foo", "1" : "bar" }
class ContainerClass implements MongoDB\BSON\Serializable {
public $things = AnotherClass4 implements MongoDB\BSON\Serializable {
private $elements = [ 0 => 'foo', 2 => 'bar' ];
function bsonSerialize() {
return $this->elements;
}
}
function bsonSerialize() {
return [ 'things' => $this->things ];
}
} // => { "things" : { "0" : "foo", "2" : "bar" } }
class ContainerClass implements MongoDB\BSON\Serializable {
public $things = AnotherClass5 implements MongoDB\BSON\Serializable {
private $elements = [ 0 => 'foo', 2 => 'bar' ];
function bsonSerialize() {
return array_values($this->elements);
}
}
function bsonSerialize() {
return [ 'things' => $this->things ];
}
} // => { "things" : [ "foo", "bar" ] }
class ContainerClass implements MongoDB\BSON\Serializable {
public $things = AnotherClass6 implements MongoDB\BSON\Serializable {
private $elements = [ 'foo', 'bar' ];
function bsonSerialize() {
return (object) $this->elements;
}
}
function bsonSerialize() {
return [ 'things' => $this->things ];
}
} // => { "things" : { "0" : "foo", "1" : "bar" } }
class UpperClass implements MongoDB\BSON\Persistable {
public $foo = 42;
protected $prot = "wine";
private $fpr = "cheese";
function bsonSerialize() {
return [ 'foo' => $this->foo, 'prot' => $this->prot ];
}
} // => { "foo" : 42, "prot" : "wine", "__pclass" : { "$type" : "80", "$binary" : "VXBwZXJDbGFzcw==" } }