PHP / Mongo:持久化模型不会反序列化

PHP / Mongo: Persistable models don't unserialize

提问人:Arno van Oordt 提问时间:8/18/2023 最后编辑:Arno van Oordt 更新时间:8/19/2023 访问量:33

问:

我正在尝试使用持久化模型作为 Mongo 文档中的值 Persistable 类如下所示:

<?php

namespace Domain\Media\Models;

use MongoDB\BSON\Persistable;

class MediaUid implements Persistable
{

    public readonly string $val;

    public function __construct(string $val)
    {
        $this->val = $val;
    }

    public function __toString()
    {
        return $this->val;
    }

    public function bsonSerialize()
    {
        return ['val' => $this->val];
    }

    public function bsonUnserialize(array $data)
    {
        $this->val = $data['val'];
    }

}

我有一个像这样的模型

<?php

namespace Domain\Collection\Models;

use Jenssegers\Mongodb\Eloquent\Model;

class SomeModel extends Model
{

    protected $connection = 'mongodb';

}

我是这样保存模型的:

$test = new SomeModel();
$test->someId = new ObjectId();
$test->someMedia = new MediaUid('1234567890');
$test->save();

序列化非常完美,文档如下所示:

$t = SomeModel::find($test->id);
print_r(json_decode($t->__toString())); // Prints:
// stdClass Object
// (
//     [_id] => 64e08963b7b5fab0a10573c3
//     [someId] => 64e08963b7b5fab0a10573c2
//     [someMedia] => stdClass Object
//         (
//             [__pclass] => stdClass Object
//                 (
//                     [$binary] => RG9tYWluXEZpbGVcTW9kZWxzXE1lZGlhVXVpZA==
//                     [$type] => 80
//                 )
//
//             [val] => 1234567890
//         )
//
//     [updated_at] => 2023-08-19T09:20:35.073000Z
//     [created_at] => 2023-08-19T09:20:35.073000Z
// )

当我读取单个值时,它现在是一个 MongoDB\BSON\ObjectIdArray(它应该是),但它仍然是一个普通数组而不是 MediaUidsomeIdsomeMedia

print_r(get_class($t->someId) . PHP_EOL); // Prints: MongoDB\BSON\ObjectIdArray
print_r(gettype($t->someMedia) . PHP_EOL); // Prints: array

关于持久性类应该如何工作的示例很少,所以我想知道我是否做错了什么或只是错过了什么?

我正在使用 Laravel,所以也许它的方式与它检索文档的方式有关?

如果不应该像这样工作,那么我想知道正确的方法应该是什么。bsonUnserialize

PS:在我的实际代码中,这些 id 到处使用(有时是深度嵌套的),因此手动将它们转换为 MediaUid 远非理想。

使用的版本:

  • PHP v8.2 版本
  • 拉拉维尔 v10.0
  • 单声道:6.0
  • Jenssegers/MongoDBdev-master
PHP Laravel MongoDB 铸造

评论

0赞 hakre 8/19/2023
您询问了 Collection::find() 的方法调用,但您错过了在问题中显示 Collection。我们现在可以假设那是什么类型的拉拉维尔魔法,无论它经常变化,所以它会导致猜测。除此之外,仅通过通用名称,我认为它没有关于具体类型的信息,并且由于没有显示 reviver,因此看起来非常正常,您在那里有一个数组结构。因此,原因不在于检索文档(根据您编写的内容工作),而是恢复它。
0赞 Arno van Oordt 8/19/2023
@hakre我改进了这个例子,所以希望它现在更干净、更清晰。SomeModel 是完全空的,除了 Laravel 对它所做的:)之外,没有任何魔法
0赞 hakre 8/19/2023
我昨天看了一下,我认为对于专门的Laravel开发人员来说,了解您如何管理它以说服Eloquent使用MongoDB服务器是很有用的。这是 Composer 所需的库,对吧?然后为了清楚起见,请命名它,因为这至少提供了良好的上下文信息。还显示MongoDB版本(服务器+PHP客户端),PHP版本。当您询问一个系统(PHP)在一天结束时与另一个系统(MongoDB)交谈时。如果你已经知道你使用的库是基于PDO还是其他东西,我认为知道也会有所帮助。
0赞 Arno van Oordt 8/19/2023
谢谢,我添加了版本。例如,在我给出的例子中,我知道如何使用 Eloquent 进行投射。然而,就像在我的实际代码中所说的那样,id 是深度嵌套的,以常规方式转换它们并不可行(无法准确解释原因)。如果没有人有下降解决方案,恐怕我必须手动进行铸造:(someMedia

答: 暂无答案