Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs 菜单
Docs 主页
/ / /
PHP 库手册
/

使用BSON数据

在本指南中,您可以学习;了解如何使用PHP库创建BSON文档并与之交互。

BSON (即 Binary JSON)是MongoDB用于组织和存储数据的数据格式。这种数据格式包括所有JSON数据结构类型,还支持其他类型,包括日期、不同大小的整数、ObjectId 值和二进制数据。PHP库提供了 MongoDB\Model\BSONArrayMongoDB\Model\BSONDocument 类型来存储BSON数据。

提示

要查看支持的BSON 类型的完整列表,请参阅MongoDB Server手册中的 BSON 类型

本指南中的代码示例引用了以下示例BSON文档:

{
"address" : {
"street" : "Pizza St",
"zipcode" : "10003"
},
"coord" : [-73.982419, 41.579505]
"cuisine" : "Pizza",
"name" : "Planet Pizza"
}

您可以使用与在PHP中创建关联大量相同的符号来创建BSON文档。将这些值插入集合时, PHP库会自动将这些值转换为BSON文档。

以下示例创建一个BSON文档来表示前面的示例BSON文档:

$document = [
'address' => [
'street' => 'Pizza St',
'zipcode' => '10003',
],
'coord' => [-73.982419, 41.579505],
'cuisine' => 'Pizza',
'name' => 'Planet Pizza',
];

您可以使用与PHP中修改关联大量相同的表示法来修改BSON文档的内容。此示例对示例BSON文档:进行了以下更改:

  • 添加值为 12345 的新 restaurant_id字段

  • name字段值更改为 "Galaxy Pizza"

$document['restaurant_id'] = 12345;
$document['name'] = 'Galaxy Pizza';

注意

前面的代码仅更改示例BSON文档在内存中的值。它不会运行任何会更改MongoDB中存储的值的数据库操作。要学习;了解如何修改存储在MongoDB中的文档,请参阅更新文档指南。

以下部分介绍如何配置应用程序序列化BSON数据的方式:

  • 类型映射:使用 typeMap 选项指定PHP类型和BSON 类型之间的默认转换。

  • 持久化类:使用 MongoDB\BSON\Persistable 接口启用序列化。

  • 枚举值:使用 bsonSerialize()bsonUnserialize() 方法指定支持的枚举与BSON值之间的序列化。

您可以在以下级别设立typeMap 选项,该选项在PHP和BSON值之间配置序列化和反序列化:

  • MongoDB\Client这将为所有操作设置默认,除非被覆盖

  • MongoDB\Database

  • MongoDB\Collection

此列表还指示了选项设置的优先级递增顺序。示例,如果为集合设立typeMap,它将覆盖数据库上设立的类型映射。

PHP库默认使用以下类型映射:

[
'array' => 'MongoDB\Model\BSONArray',
'document' => 'MongoDB\Model\BSONDocument',
'root' => 'MongoDB\Model\BSONDocument',
]

此类型映射在两个方向上执行以下转换:

  • 数组到MongoDB\Model\BSONArray对象

  • 顶级和嵌入式BSON文档到MongoDB\Model\BSONDocument对象

类型映射可以指定任何实现MongoDB\ BSON\Unserializable 接口的类。它还可以指定arraystdClassobject 类型的转换。

以下示例为将数组和BSON文档序列化为 MongoDB\Model\BSONDocument 对象的 restaurants集合设置 typeMap 选项:

$options = [
'typeMap' => [
'array' => 'MongoDB\Model\BSONDocument',
'root' => 'MongoDB\Model\BSONDocument',
'document' => 'MongoDB\Model\BSONDocument',
],
];
$db->createCollection('restaurants', $options);

您可以创建实现MongoDB\ BSON\Persistable 接口的类。此接口指示PHP库根据PHP扩展的持久性规范自动执行序列化和反序列化,而无需使用 选项。 typeMapPersistable接口类似于 PHP 的 Serializable 接口。

从BSON反序列化PHP变量时,Persistable对象的编码类名会覆盖 typeMap 选项中指定的任何类。但是,它不会覆盖 arraystdClassobject 类型。

考虑以下 Person 类定义,它实现了 Persistable 接口并指定了如何将对象字段序列化和反序列化为BSON值:

class Person implements MongoDB\BSON\Persistable
{
private \MongoDB\BSON\ObjectId $id;
private \MongoDB\BSON\UTCDateTime $createdAt;
public function __construct(private string $name)
{
$this->id = new \MongoDB\BSON\ObjectId();
$this->createdAt = new \MongoDB\BSON\UTCDateTime();
}
public function bsonSerialize(): array
{
return [
'_id' => $this->id,
'name' => $this->name,
'createdAt' => $this->createdAt,
];
}
public function bsonUnserialize(array $data): void
{
$this->id = $data['_id'];
$this->name = $data['name'];
$this->createdAt = $data['createdAt'];
}
}

以下示例构造一个Person对象,将其插入数据库,然后将其作为相同类型的对象读回:

$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)
}
}

返回的文档相当于以下BSON文档:

{
"_id" : ObjectId("56fad2c36118fd2e9820cfc1"),
"__pclass" : BinData(128,"UGVyc29u"),
"name" : "Bob",
"createdAt" : ISODate("2016-03-29T19:08:51.218Z")
}

PHP库自动添加 __pclass字段来追踪文档相应的类名,这样您就可以将文档反序列化为 Person对象。

注意

您只能将 Persistable 接口用于根文档和嵌入式BSON文档,而不能用于BSON数组。

您可以将支持的枚举序列化和反序列化为BSON数据。支持的枚举值会序列化为其大小写值,而没有大小写值的纯枚举无法直接序列化。要执行这些转换,您必须通过在类定义中定义 bsonSerialize()bsonUnserialize() 方法来指定序列化逻辑。

提示

要学习;了解有关支持枚举的更多信息,请参阅PHP扩展文档中的支持枚举。

考虑以下名为 Role 的支持枚举,它有两个整数值的情况:

enum Role: int
{
case USER = 1;
case ADMIN = 2;
}

User 类定义包括一个具有 Role枚举值的 role字段,并指定将其字段序列化和反序列化为BSON值的逻辑:

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']);
}
}

以下示例构造一个带有 role字段的 User对象,将其插入数据库,并将其作为相同类型的对象读回:

$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) "..."
}
}

注意

枚举无法实现MongoDB\BSON\UnserializableMongoDB\BSON\Persistable 接口,因为枚举没有状态,也无法像类对象一样进行实例化。但是,纯枚举和支持枚举可以实现MongoDB\BSON\Serializable,您可以使用它来覆盖默认的枚举序列化行为。

要进一步学习;了解本指南中讨论的PHP库方法或类型,请参阅以下库API文档:

要学习;了解有关本指南中讨论的PHP扩展类型的更多信息,请参阅以下扩展API文档:

后退

Decimal128

在此页面上