Docs 菜单
Docs 主页
/ / /
PHP 库手册
/

对 BSON 数据建模

在此页面上

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

大多数从MongoDB读取数据的方法都支持 typeMap选项,该选项允许控制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 手册中

扩展的 持久性规范 概述了类如何实现其 MongoDB\ BSON\Persistable 接口被序列化为 BSON 或从BSON反序列化。Persistable 接口类似于 PHP 的 Serializable 接口。

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

注意

从 BSON 反序列化 PHP 变量时, Persistable 的编码类名 对象将覆盖类型映射中指定的任何类,但不会覆盖"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 一起使用,并将序列化为其大小写值(即整数或string )。 纯枚举 ,没有支持的案例,无法直接序列化。这类似于 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\Unserializable MongoDB\BSON\Persistable ,因为枚举没有状态,也不能像普通对象一样实例化。但是,纯枚举和支持枚举可以实现 MongoDB\BSON\Serializable ,它可用于克服默认行为,即支持的枚举会序列化为其案例值,而纯枚举无法序列化。

后退

Decimal128