太久没接触laravel,之前公司的项目还是5.6的时代,现在最新的是12了,访问器的写法有改变了:


  */
    protected $appends = [
        'price_with_tax', // 5. 将新属性的名称添加到这里
    ];

    // ... priceWithTax() 方法 ...
    protected function priceWithTax(): Attribute
    {
        return Attribute::make(
            get: fn ($value, $attributes) => 
                round($attributes['price'] * (1 + $attributes['tax_rate']), 2)
        );
    }

结果我得到的响应是:

`"grade_level": {

                    "get": {},

                    "set": null,

                    "withCaching": false,

                    "withObjectCaching": true

                }`

不符合预期。
经过一翻查找,得出问题的原因。
之前看到的输出是 Attribute 对象本身的序列化结果,而不是它计算后的值。

问题的原因几乎可以肯定是:访问器方法声明为了 public,而它必须是 protected。

为什么必须是 protected?
在 Laravel 中,Eloquent 的魔术属性访问机制有特定的工作流程。当您使用新的 Attribute 风格定义访问器时:

如果方法是 protected:Laravel 会识别出这是一个特殊的属性定义。当您访问 $model->grade_level 时,Laravel 不会直接返回 Attribute 对象,而是会调用其内部的 get 回调函数,并将计算结果作为属性的值。

如果方法是 public:Laravel 会将其视为一个普通的公共方法。当魔术属性访问机制查找 grade_level 时,它会找到一个同名的公共方法 gradeLevel(),直接调用它,然后将该方法的返回值(也就是那个 Attribute 对象本身)赋给 grade_level 属性。因此,在序列化时,您看到的就是这个 Attribute 对象的内部结构。

标签: none

添加新评论