Work with BSON Data
Overview
In this guide, you can learn how to create and interact with BSON documents by using the PHP library.
BSON, or Binary JSON, is the data format that MongoDB uses to organize
and store data. This data format includes all JSON data structure types and
also supports other types, including dates, different-sized integers, ObjectId
values, and binary data. The PHP library provides the MongoDB\Model\BSONArray
and MongoDB\Model\BSONDocument
types to store BSON data.
Tip
To view a complete list of supported BSON types, see BSON Types in the MongoDB Server manual.
Sample Data
The code examples in this guide reference the following sample BSON document:
{ "address" : { "street" : "Pizza St", "zipcode" : "10003" }, "coord" : [-73.982419, 41.579505] "cuisine" : "Pizza", "name" : "Planet Pizza" }
Create a BSON Document
You can create a BSON document by using the same notation that you use to create an associative array in PHP. The PHP library automatically converts these values into BSON documents when inserting them into a collection.
The following example creates a BSON document that represents the preceding sample BSON document:
$document = [ 'address' => [ 'street' => 'Pizza St', 'zipcode' => '10003' ], 'coord' => [-73.982419, 41.579505], 'cuisine' => 'Pizza', 'name' => 'Planet Pizza' ];
Change a BSON Document
You can modify the contents of a BSON document by using the same notation that you use to modify an associative array in PHP. This example makes the following changes to the sample BSON document:
Adds a new
restaurant_id
field that has a value of12345
Changes the
name
field value to"Galaxy Pizza"
$document['restaurant_id'] = 12345; $document['name'] = 'Galaxy Pizza';
Note
The preceding code changes only the in-memory values of the sample BSON document. It does not run any database operations that change values stored in MongoDB. To learn how to modify documents stored in MongoDB, see the Update Documents guide.
Customize BSON Serialization
The following sections describe how to configure the way your application serializes BSON data:
Type Maps: Use the
typeMap
option to specify the default conversion between PHP types and BSON types.Persistable Classes: Use the
MongoDB\BSON\Persistable
interface to enable serialization.Enum Values: Use the
bsonSerialize()
andbsonUnserialize()
methods to specify serialization between backed enums and BSON values.
Type Maps
You can set the typeMap
option, which configures serialization and
deserialization between PHP and BSON values, at the following levels:
MongoDB\Client
, which sets the default for all operations unless overriddenMongoDB\Database
MongoDB\Collection
This list also indicates the increasing order of precedence of the option settings. For
example, if you set a typeMap
for a collection, it will override the type map
set on the database.
The PHP library uses the following type map by default:
[ 'array' => 'MongoDB\Model\BSONArray', 'document' => 'MongoDB\Model\BSONDocument', 'root' => 'MongoDB\Model\BSONDocument', ]
This type map performs the following conversions in both directions:
Arrays to
MongoDB\Model\BSONArray
objectsTop-level and embedded BSON documents to
MongoDB\Model\BSONDocument
objects
A type map can specify any class that implements the
MongoDB\BSON\Unserializable interface.
It can also specify conversions of the array
, stdClass
, and object
types.
Custom Type Map Example
The following example sets the typeMap
option for the restaurants
collection
that serializes arrays and BSON documents as MongoDB\Model\BSONDocument
objects:
$options = [ 'typeMap' => [ 'array' => 'MongoDB\Model\BSONDocument', 'root' => 'MongoDB\Model\BSONDocument', 'document' => 'MongoDB\Model\BSONDocument' ] ]; $db->createCollection('restaurants', $options);
Persistable Classes
You can create classes that implement the MongoDB\BSON\Persistable
interface. This interface instructs the PHP library to automatically perform serialization
and deserialization according to the PHP extension's persistence specification without requiring the typeMap
option. The Persistable
interface
is analogous to PHP's Serializable interface.
When deserializing a PHP variable from BSON, the encoded class name of a
Persistable
object overrides any class specified in the typeMap
option.
However, it does not override array
, stdClass
, or object
types.
Example
Consider the following Person
class definition, which implements the
Persistable
interface and specifies how to serialize and deserialize
object fields as BSON values:
class Person implements MongoDB\BSON\Persistable { private MongoDB\BSON\ObjectId $id; private string $name; private MongoDB\BSON\UTCDateTime $createdAt; public function __construct(string $name) { $this->id = new MongoDB\BSON\ObjectId; $this->name = $name; $this->createdAt = new MongoDB\BSON\UTCDateTime; } function bsonSerialize() { return [ '_id' => $this->id, 'name' => $this->name, 'createdAt' => $this->createdAt, ]; } function bsonUnserialize(array $data) { $this->id = $data['_id']; $this->name = $data['name']; $this->createdAt = $data['createdAt']; } }
The following example constructs a Person
object, inserts it into the
database, and reads it back as an object of the same type:
$collection = $client->test->persons; $result = $collection->insertOne(new Person('Bob')); $person = $collection->findOne(['_id' => $result->getInsertedId()]); var_dump($person);
object(Person)#18 (3) { ["id":"Person":private]=> object(MongoDB\BSON\ObjectId)#15 (1) { ["oid"]=> string(24) "56fad2c36118fd2e9820cfc1" } ["name":"Person":private]=> string(3) "Bob" ["createdAt":"Person":private]=> object(MongoDB\BSON\UTCDateTime)#17 (1) { ["milliseconds"]=> int(1459278531218) } }
The returned document is equivalent to the following BSON document:
{ "_id" : ObjectId("56fad2c36118fd2e9820cfc1"), "__pclass" : BinData(128,"UGVyc29u"), "name" : "Bob", "createdAt" : ISODate("2016-03-29T19:08:51.218Z") }
The PHP library automatically adds the __pclass
field to keep
track of the document's corresponding class name, which allows you to
deserialize the document into a Person
object.
Note
You can use the Persistable
interface for root and embedded BSON documents
only, not BSON arrays.
Enum Values
You can serialize and deserialize backed enums into BSON data. Backed
enum values serialize as their case value, while pure enums without
case values cannot be directly serialized. To perform these conversions,
you must specify serialization logic by defining the bsonSerialize()
and bsonUnserialize()
methods in your class definition.
Tip
To learn more about backed enums, see Backed enums in the PHP extension documentation.
Example
Consider the following User
class definition, which specifies
logic for serializing and deserializing its fields into BSON values.
The class includes a role
field, which has a backed enum value:
enum Role: int { case USER = 1; case ADMIN = 2; } class User implements MongoDB\BSON\Persistable { public function __construct( private string $username, private Role $role, private MongoDB\BSON\ObjectId $_id = new MongoDB\BSON\ObjectId(), ) {} public function bsonSerialize(): array { return [ '_id' => $this->_id, 'username' => $this->username, 'role' => $this->role, ]; } public function bsonUnserialize(array $data): void { $this->_id = $data['_id']; $this->username = $data['username']; $this->role = Role::from($data['role']); } }
The following example constructs a User
object with a role
field,
inserts it into the database, and reads it back as an object of the same type:
$collection = $client->test->users; $result = $collection->insertOne(new User('alice', Role::USER)); $person = $collection->findOne(['_id' => $result->getInsertedId()]); var_dump($person);
object(User)#40 (3) { ["username":"User":private]=> string(5) "alice" ["role":"User":private]=> enum(Role::USER) ["_id":"User":private]=> object(MongoDB\BSON\ObjectId)#38 (1) { ["oid"]=> string(24) "..." } }
Note
Enums cannot implement the MongoDB\BSON\Unserializable
and
MongoDB\BSON\Persistable
interfaces because enum cases have no
state and cannot be instantiated like class objects. However, pure and backed
enums can implement MongoDB\BSON\Serializable
, which you can use to
override the default enum serialization behavior.
API Documentation
To learn more about any of the PHP library methods or types discussed in this guide, see the following library API documentation:
To learn more about the PHP extension types discussed in this guide, see the following extension API documentation: