Serialization to BSON

Arrays

If an array is a packed array — i.e. the keys start at 0 and are sequential without gaps: BSON array.

If the array is not packed — i.e. having associative (string) keys, the keys don't start at 0, or when there are gaps:: BSON object

A top-level (root) document, always serializes as a BSON document.

Examples

These serialize as a BSON array:

[ 8, 5, 2, 3 ] => [ 8, 5, 2, 3 ]
[ 0 => 4, 1 => 9 ] => [ 4, 9 ]

These serialize as a BSON document:

[ 0 => 1, 2 => 8, 3 => 12 ] => { "0" : 1, "2" : 8, "3" : 12 }
[ "foo" => 42 ] => { "foo" : 42 }
[ 1 => 9, 0 => 10 ] => { "1" : 9, "0" : 10 }

Note that the five examples are extracts of a full document, and represent only one value inside a document.

Objects

If an object is of the stdClass class, serialize as a BSON document.

If an object is a supported class that implements MongoDB\BSON\Type, then use the BSON serialization logic for that specific type. MongoDB\BSON\Type instances (excluding MongoDB\BSON\Serializable may only be serialized as a document field value. Attempting to serialize such an object as a root document will throw a MongoDB\Driver\Exception\UnexpectedValueException

If an object is of an unknown class implementing the MongoDB\BSON\Type interface, then throw a MongoDB\Driver\Exception\UnexpectedValueException

If an object is of any other class, without implementing any special interface, serialize as a BSON document. Keep only public properties, and ignore protected and private properties.

If an object is of a class that implements the MongoDB\BSON\Serializable interface, call MongoDB\BSON\Serializable::bsonSerialize() and use the returned array or stdClass to serialize as a BSON document or array. The BSON type will be determined by the following:

  1. Root documents must be serialized as a BSON document.

  2. MongoDB\BSON\Persistable objects must be serialized as a BSON document.

  3. If MongoDB\BSON\Serializable::bsonSerialize() returns a packed array, serialize as a BSON array.

  4. If MongoDB\BSON\Serializable::bsonSerialize() returns a non-packed array or stdClass, serialize as a BSON document.

  5. If MongoDB\BSON\Serializable::bsonSerialize() did not return an array or stdClass, throw an MongoDB\Driver\Exception\UnexpectedValueException exception.

If an object is of a class that implements the MongoDB\BSON\Persistable interface (which implies MongoDB\BSON\Serializable), obtain the properties in a similar way as in the previous paragraphs, but also add an additional property __pclass as a Binary value, with subtype 0x80 and data bearing the fully qualified class name of the object that is being serialized.

The __pclass property is added to the array or object returned by MongoDB\BSON\Serializable::bsonSerialize(), which means it will overwrite any __pclass key/property in the MongoDB\BSON\Serializable::bsonSerialize() return value. If you want to avoid this behaviour and set your own __pclass value, you must not implement MongoDB\BSON\Persistable and should instead implement MongoDB\BSON\Serializable directly.

Examples

<?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 = [ => 'foo'=> '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 = [ => 'foo'=> '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==" } }