文档菜单
文档首页
/ / /
PHP库手册
/

建模BSON数据

本页内容

  • 类型映射
  • 可持久化类
  • 使用枚举

大多数从MongoDB读取数据的方法都支持一个类型映射选项,该选项允许控制BSON如何转换为PHP。此外,还有MongoDB\ClientMongoDB\DatabaseMongoDB\Collection 类接受一个 typeMap 选项,该选项可以用于指定应用于任何支持的方法和所选类的默认类型映射(例如 MongoDB\Client::selectDatabase())。

MongoDB\ClientMongoDB\DatabaseMongoDB\Collection 类默认使用以下类型映射

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

上述类型映射将分别将 BSON 文档和数组转换为 MongoDB\Model\BSONDocumentMongoDB\Model\BSONArray 对象。使用 rootdocument 键来区分顶层 BSON 文档和嵌入文档。

类型映射可以指定任何实现了MongoDB\BSON\Unserializable 以及 "array""stdClass""object""stdClass""object" 是彼此的别名)的类。

提示

另请参阅

从BSON反序列化 在PHP手册中

The extension's persistence specification outlines how classes implementing its MongoDB\BSON\Persistable interface are serialized to and deserialized from BSON. The Persistable interface is analogous to PHP's Serializable interface.

该扩展自动处理实现 可持久化 接口类的序列化和反序列化,无需使用 typeMap 选项。这是通过在BSON文档中特殊属性中编码PHP类的名称来完成的。

注意

在从 BSON 反序列化 PHP 变量时,一个 可持久化 对象的编码类名将覆盖类型映射中指定的任何类,但它不会覆盖 "array" 以及 "stdClass""object"。这在 持久化规范 中有所讨论,但需要重复强调。

考虑以下类定义

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

以下示例创建了一个 Person 对象,将其插入数据库,并以相同类型的对象读取它

<?php
$collection = (new MongoDB\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)
}
}

在 MongoDB Shell 中,相同的文档可能显示为

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

注意

MongoDB\BSON\Persistable 只能用于根和嵌套 BSON 文档。它不能用于 BSON 数组。

受支持的枚举可以与BSON一起使用,并将其序列化为它们的case值(即整数或字符串)。纯枚举没有受支持的case,不能直接序列化。这与json_encode().处理枚举的方式相似。

将后端枚举通过BSON进行往返操作需要特殊处理。以下示例中,包含枚举的类中的bsonUnserialize()方法负责将值转换回枚举实例

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

枚举不能实现MongoDB\BSON\UnserializableMongoDB\BSON\Persistable接口,因为枚举实例没有状态,不能像普通对象那样实例化。然而,纯枚举和后端枚举可以实现MongoDB\BSON\Serializable接口,这可以用来克服后端枚举默认序列化为其实例值,而纯枚举不能序列化的行为。

返回

Decimal128