如何处理 Laravel Eloquent 模型中的嵌套对象?

发布于 2025-01-11 05:26:36 字数 2297 浏览 0 评论 0原文

我有一个对象,创建如下: $object = new Object($datas)

这里,$datas 是一个数组(来自 API,而不是数据库)

$datas = [
    'prop1' => 'value1',
    'prop2' => 'value2',
    'prop3' => 'value3',
    'nestedObject' => [
        'propa' => 'valuea',
        'propb' => 'valueb',
        'propc' => 'valuec',
    ],
];

如果我什么都不做,$object->nestedObject 就是一个数组。 但是,我希望它是一个实现 NestedObject 类的对象。


为了做到这一点,我为nestedObject属性定义了一个强制转换:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Object extends Model
{
    protected $guarded = [];

    protected $casts = [
        'nestedObject' => \App\Casts\NestedObjectCast::class,
    ];
}

并且NestedObjectCast:

<?php

namespace App\Casts;

use App\Models\NestedObject as NestedObjectModel;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use InvalidArgumentException;

class NestedObjectCast implements CastsAttributes
{
    /**
     * Cast the given value.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  mixed  $value
     * @param  array  $attributes
     * @return \App\Models\NestedObject
     */
    public function get($model, $key, $value, $attributes)
    {
        if($value !== null) {
            return new NestedObjectModel($value);
        }
    }

    /**
     * Prepare the given value for storage.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  \App\Models\NestedObject $value
     * @param  array  $attributes
     * @return array
     */
    public function set($model, $key, $value, $attributes)
    {
        return [$key => $value];
    }
}

它有效! 现在,$object->nestedObject 是 NestedObject 类的一个实例。

但有件事困扰着我:在 NestedObjectCast 类中,在 set() 方法中,$value 应该是 NestedObject 类的实例(文档是这么说的),但事实并非如此< /强>。当我在此方法中编写 var_dump() 时,$value 是一个数组或 null。

所以,显然,即使它有效,我的代码也有问题,但是什么???
另外,我有点惊讶我必须编写一个 NestedObjectCast 类来执行如此简单的操作。 还有其他/更好的方法吗?

I have an object, created like this : $object = new Object($datas)

Here, $datas is an array (coming from an API, not a database) :

$datas = [
    'prop1' => 'value1',
    'prop2' => 'value2',
    'prop3' => 'value3',
    'nestedObject' => [
        'propa' => 'valuea',
        'propb' => 'valueb',
        'propc' => 'valuec',
    ],
];

If I do nothing, $object->nestedObject is an array.
However, I want it to be an object implementing the NestedObject class.


In order to do that, I defined a cast for the nestedObject property :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Object extends Model
{
    protected $guarded = [];

    protected $casts = [
        'nestedObject' => \App\Casts\NestedObjectCast::class,
    ];
}

And the NestedObjectCast :

<?php

namespace App\Casts;

use App\Models\NestedObject as NestedObjectModel;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use InvalidArgumentException;

class NestedObjectCast implements CastsAttributes
{
    /**
     * Cast the given value.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  mixed  $value
     * @param  array  $attributes
     * @return \App\Models\NestedObject
     */
    public function get($model, $key, $value, $attributes)
    {
        if($value !== null) {
            return new NestedObjectModel($value);
        }
    }

    /**
     * Prepare the given value for storage.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  \App\Models\NestedObject $value
     * @param  array  $attributes
     * @return array
     */
    public function set($model, $key, $value, $attributes)
    {
        return [$key => $value];
    }
}

It works !
Now, $object->nestedObject is an instance of the class NestedObject.

But something bothers me : In the NestedObjectCast class, in the set() method, $value should be an instance of NestedObject class (That what the documentation say), but it's not the case. When I write a var_dump() inside this method, $value is an array or null.

So, obviously, even if it works, there is something wrong with my code, but what ???
Also, I was a bit surprised that I have to write a NestedObjectCast class to do such simple action. Is there another/better way to do this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

行雁书 2025-01-18 05:26:36

如果你想通过命令 $object = new Obj($datas); 获取 NestedObject 数组,只需在 Object 类中构建一个构造函数,就像我的 Obj 类一样:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\NestedObject as NestedObjectModel;

class Obj extends Model
{
    protected $guarded = [];

    protected $casts = [
        'nestedObject' => \App\Casts\NestedObjectCast::class,
    ];

    public function __construct(array $attributes = []) {
        if (!empty($attributes['nestedObject'])) {
            $attributes['nestedObject'] = new NestedObjectModel($attributes['nestedObject']);
        }
        parent::__construct($attributes);

    }
}

注意:无法创建名为 Object 的类,因为它是 PHP 中的保留字。

If you want get an array of NestedObject by command $object = new Obj($datas);, just build a construct function in Object class like my Obj class:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\NestedObject as NestedObjectModel;

class Obj extends Model
{
    protected $guarded = [];

    protected $casts = [
        'nestedObject' => \App\Casts\NestedObjectCast::class,
    ];

    public function __construct(array $attributes = []) {
        if (!empty($attributes['nestedObject'])) {
            $attributes['nestedObject'] = new NestedObjectModel($attributes['nestedObject']);
        }
        parent::__construct($attributes);

    }
}

Note: Can not create class with name Object, because it’s a reserved word in PHP.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文