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\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.
<?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';
public function bsonSerialize(): array
{
return ['foo' => $this->foo, 'prot' => $this->prot];
}
} // => {"foo": 42, "prot": "wine"}
class AnotherClass2 implements MongoDB\BSON\Serializable
{
public $foo = 42;
public function bsonSerialize(): self
{
return $this;
}
} // => MongoDB\Driver\Exception\UnexpectedValueException("bsonSerialize() did not return an array or stdClass")
class AnotherClass3 implements MongoDB\BSON\Serializable
{
private $elements = ['foo', 'bar'];
public function bsonSerialize(): array
{
return $this->elements;
}
} // => {"0": "foo", "1": "bar"}
/**
* Nesting Serializable classes
*/
class AnotherClass4 implements MongoDB\BSON\Serializable
{
private $elements = [0 => 'foo', 2 => 'bar'];
public function bsonSerialize(): array
{
return $this->elements;
}
} // => {"0": "foo", "2": "bar"}
class ContainerClass1 implements MongoDB\BSON\Serializable
{
public $things;
public function __construct()
{
$this->things = new AnotherClass4();
}
function bsonSerialize(): array
{
return ['things' => $this->things];
}
} // => {"things": {"0": "foo", "2": "bar"}}
class AnotherClass5 implements MongoDB\BSON\Serializable
{
private $elements = [0 => 'foo', 2 => 'bar'];
public function bsonSerialize(): array
{
return array_values($this->elements);
}
} // => {"0": "foo", "1": "bar"} as a root class
// ["foo", "bar"] as a nested value
class ContainerClass2 implements MongoDB\BSON\Serializable
{
public $things;
public function __construct()
{
$this->things = new AnotherClass5();
}
public function bsonSerialize(): array
{
return ['things' => $this->things];
}
} // => {"things": ["foo", "bar"]}
class AnotherClass6 implements MongoDB\BSON\Serializable
{
private $elements = ['foo', 'bar'];
function bsonSerialize(): object
{
return (object) $this->elements;
}
} // => {"0": "foo", "1": "bar"}
class ContainerClass3 implements MongoDB\BSON\Serializable
{
public $things;
public function __construct()
{
$this->things = new AnotherClass6();
}
public function bsonSerialize(): array
{
return ['things' => $this->things];
}
} // => {"things": {"0": "foo", "1": "bar"}}
class UpperClass implements MongoDB\BSON\Persistable
{
public $foo = 42;
protected $prot = 'wine';
private $fpr = 'cheese';
private $data;
public function bsonUnserialize(array $data): void
{
$this->data = $data;
}
public function bsonSerialize(): array
{
return ['foo' => $this->foo, 'prot' => $this->prot];
}
} // => {"foo": 42, "prot": "wine", "__pclass": {"$type": "80", "$binary": "VXBwZXJDbGFzcw=="}}
?>
Deserialization from BSON
Warning
BSON documents can technically contain duplicate keys because documents are
stored as a list of key-value pairs; however, applications should refrain
from generating documents with duplicate keys as server and driver behavior
may be undefined. Since PHP objects and arrays cannot have duplicate keys,
data could also be lost when decoding a BSON document with duplicate keys.
The legacy mongo extension deserialized
both BSON documents and arrays as PHP arrays. While PHP arrays are
convenient to work with, this behavior was problematic because different
BSON types could deserialize to the same PHP value (e.g.
{"0": "foo"} and ["foo"]) and make it
impossible to infer the original BSON type. By default, the
mongodb extension addresses this concern by ensuring that BSON
arrays and documents are converted to PHP arrays and objects, respectively.
For compound types, there are three data types:
root
refers to the top-level BSON document only
document
refers to embedded BSON documents only
array
refers to a BSON array
Besides the three collective types, it is also possible to configure
specific fields in your document to map to the data types mentioned below.
As an example, the following type map allows you to
map each embedded document within an "addresses" array to
an Address class and each
"city" field within those embedded address documents to
a City class:
A BSON document (root or embedded) without a
__pclass property
[1]
A __pclass property is only deemed to exist if
there exists a property with that name, and it is a Binary value,
and the sub-type of the Binary value is 0x80. If any of these three
conditions is not met, the __pclass property does not exist and
should be treated as any other normal property.
becomes a PHP stdClass object, with each
BSON document key set as a public stdClass
property.
A BSON document (root or embedded) with a
__pclass property [1] becomes a PHP object of
the class name as defined by the __pclass
property.
If the named class does not exist or does not implement the
MongoDB\BSON\Persistable interface,
stdClass will be used and each BSON document
key (including __pclass) will be set as a
public stdClass property.
The __pclass functionality relies on the
property being part of a retrieved MongoDB document. If you use a
projection
when querying for documents, you need to include the
__pclass field in the projection for this
functionality to work.
"array"
Turns a BSON array or BSON document into a PHP array. There will be no
special treatment of a __pclass property [1],
but it may be set as an element in the returned array if it was
present in the BSON document.
"object" or "stdClass"
Turns a BSON array or BSON document into a
stdClass object. There will be no special
treatment of a __pclass property [1], but it may
be set as a public property in the returned object if it was present
in the BSON document.
The bson value is only available for the three root
types, not in the field specific mappings.
any other string
Defines the class name that the BSON array or BSON object should be
deserialized as. For BSON objects that include
__pclass properties, that class will take
priority.
If the BSON object has a __pclass property and
that class exists and implements
MongoDB\BSON\Persistable it will
supersede the class provided in the type map.
The properties of the BSON document, including
the __pclass property if it exists, will be sent
as an associative array to the
MongoDB\BSON\Unserializable::bsonUnserialize()
function to initialise the object's properties.
The MongoDB\BSON\Unserializable::bsonUnserialize()
method of YourClass, OurClass, TheirClass iterate over the array and set
the properties without modifications. It also sets
the $unserialized property to true: