访问器和构造函数的问题

我在model里,定义了一个属性,protected $user_id = ‘’”;
然后控制器调用这个model的时候传入了一个user_id,然后我在__construct里面获取传入的user_id,将他赋值给$user_id。

然后我又在model里定义了一个访问器,但是在访问器里无法获取$user_id

应该是访问器先被初始化,如何解决这个问题呢
下面是model代码

下面是控制器代码

示例代码

<?php
    //MODEL文件
    class Good extends Model
    {
        protected   $table          = 'goods';
        public      $timestamps     = false;
        public      $user_id        = 0;
        protected   $appends        = ['viprice',];
        public function construct($user_id) {
            parent::construct();
            return $this->user_id = $user_id;
        }
        public function getVipriceAttribute($val){
            //先用$user_id去获取客户信息,获取客户的等级
            $userInfo = (new User())->getUserInfo($this->user_id);
            //然后获取根据用户的等级返回不同的商品价格
            switch ($userInfo->level){
                case 1:
                    return $this->vipPrice_1;//vipPrice_1是数据库中goods表中的字段
                case 2:
                    return $this->vipPrice_2;//vipPrice_2是数据库中goods表中的字段
                default:
                    return 9999;//如果没有会员ID直接返回上商品9999的价格
            }
        }
        //这里是获取商品信息
        public function goodInfo($gid)
        {
            //通过商品ID返回商品的信息
            return $this->where('id',$gid)->first();
        }

    }



    //控制器文件
    class HomeController extends Controller
    {

        public function item()
        {

            $gid        = $_GET['gid']; //获取商品ID
            $user_id    = 1;            //模拟会员ID,不能用session获取,因为是api接口,没有session
            $good = (new Good($user_id))->goodInfo($gid);

            //输出当前用户的商品价格
            dd($good->viprice);
        }


    }
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 17

Model 在实例化时会先初始化属性,然后才会调用构造函数。因此,当你在构造函数中赋值给 $user_id 时,访问器已经被初始化了,并且无法获取到最新的 $user_id 值。

通过使用 setAttribute 方法来设置属性值,可以确保属性值在访问器中是最新的。 另外,你也可以使用 Laravel 提供的 setRawAttributes 方法来设置属性值,这个方法可以直接设置属性值,而不需要使用 setAttribute 方法。

// 在构造函数中设置属性值
public function __construct(array $attributes = [])
{
    parent::__construct($attributes);
    $this->setRawAttributes(['user_id' => $attributes['user_id']], true);
}
2个月前 评论
祝柠好运 (楼主) 2个月前

虽然我不知道你的需求,但总感觉哪里有问题,你是怎么在模型里写__construct的?

2个月前 评论
protected int $custom_user_id;
    protected $appends = ['custom_user_id'];

    protected $guarded = [];
    public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);
        $this->custom_user_id = $attributes['custom_user_id'] ?? 0;
    }

    public function customUserId(): int
    {
        return $this->custom_user_id;
    }

file

如果是这样的话,我猜是每次查询的时候new了一个新的模型

2个月前 评论

定义属性没什么用,访问器是从 $attributes 属性里拿的,得往 $attributes 添加,一般直接赋值就行 $model->user_id = $user_id,这么赋值得把自定义的 $user_id 属性删除才行。⌈调用这个 model 的时候传入了一个 user_id⌋,怎么传的?上代码

2个月前 评论
php_yt (作者) 1个月前

模型

class AdCategory extends Model
{

    protected $fillable = ['user_id'];

    public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);
    }

    public function getUserIdAttribute()
    {
        return $this->attributes['user_id'].' (from accessor)';
    }
}

控制器调用

public function test_set_raw_attributes()
    {
        $user = new AdCategory;
        $user->setRawAttributes(['user_id' => 2], true);
        dd($user->user_id);
    }

file

public function item(array $data): array
    {
        // 获取并验证参数
        $userId = (int) Arr::get($data, 'userId', 0);
        $goodsId = (int) Arr::get($data, 'goodsId', 0);
        // 查询商品和用户信息
        $goods = Goods::query()->where('gid', $goodsId)->first();
        $user = Users::query()->find($userId);

        // 验证数据存在性
        ExUtil::status($user, StatusCode::VALIDATE_ERROR, '用户不存在');
        ExUtil::status($goods, StatusCode::VALIDATE_ERROR, '商品不存在');

        // 获取用户等级和商品价格
        $level = (int) Arr::get($user, 'level', 0);
        $price = $this->getPrice($user, $goods);

        return [
            'price' => $price,
        ];
    }

    /**
     * 根据用户等级获取商品价格
     * 
     * @param Model $user 用户模型实例
     * @param Model $goods 商品模型实例
     * @return string 格式化后的商品价格,默认返回"9999"
     */
    private function getPrice(Model $user, Model $goods): string 
    {
        // 获取用户等级
        $level = (int) Arr::get($user, 'level', 0);

        // 获取对应等级的商品价格
        return (string) Arr::get($goods, 'viprice_' . $level, '9999');
    }
1个月前 评论
祝柠好运 (楼主) 1个月前
莫名私下里 (作者) 1个月前

虚拟属性append应该能满足你的需求吧。

class test extends Model 
{
    protected $appends = array(
        "user_id",
    );

     public function getUserIdAttribute()
    {
        return $this->attributes["user_id"] + 1;
    }
}
        $a = (new test(array("user_id" => 1)));
        dd($a->user_id);
        // result = 2
1个月前 评论
祝柠好运 (楼主) 1个月前
fofome (作者) 1个月前
fofome (作者) 1个月前
fofome (作者) 1个月前
sanders

首先 PHP 的构造方法是 __construct 不是 construct。

其次,模型不是楼主这样用的哦。商品查出来如果想根据会员等级返回对应的价格字段可以在 APIResource 里面做逻辑。文档链接:API 资源《Laravel 11 中文文档》

1个月前 评论
sanders (作者) 1个月前
GDDD

看了下回答,都是牛头不对马嘴。我必须要回答下。 这不就是类与对象吗? 如果用同上的实例,肯定可以获取use_id 每次都是一个新的实例,按照你的写法 无解!!!!

1个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!