You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yii2用户授权报错:Call to a member function get() on null求助

排查"Call to a member function get() on null"报错的原因及解决方案

这个报错的核心是你在调用$user->balance->get(...)时,$user->balance返回了null——也就是说当前用户对应的UserBalance记录不存在,或者关联关系没正确建立。结合你的代码,主要问题出在以下几个关键点:

1. 重写的signup方法未执行父类核心逻辑,导致User记录未创建或关联ID错误

看你的RegistrationForm.php里的signup方法:

public function signup() {
    \Yii::$app->db->transaction(function() {
        (new UserBalance([
            'user_id' => $this->id,
            'silver_in' => 100
        ]))->save();
        $value = SettingHelper::get('user.count') + rand(1, 10);
        SettingHelper::set('user.count', $value);
    });
}

你完全覆盖了父类的signup方法,但没有调用parent::signup()——而dektrium/yii2-user的父类方法才是负责创建User记录、生成用户ID的核心流程。

这会引发两个致命问题:

  • $this->id此时根本没有值(因为User记录还没被创建),导致你创建的UserBalance的user_id为null,后续用户登录后,$user->balance找不到对应记录,自然返回null。
  • 父类的注册逻辑没执行,用户的基础记录都没创建成功,整个注册流程不完整。

修复方案:

先调用父类方法完成User记录的创建,再用返回的User实例ID去创建UserBalance:

public function signup() {
    // 先执行父类逻辑,创建User记录并返回实例
    $user = parent::signup();
    if ($user === null) {
        return null; // 父类创建失败时直接返回,终止流程
    }

    \Yii::$app->db->transaction(function() use ($user) {
        $balance = new UserBalance([
            'user_id' => $user->id, // 使用已创建的User实例的有效ID
            'silver_in' => 100
        ]);
        // 可以根据需求选择是否跳过验证,或者添加错误处理
        if (!$balance->save()) {
            throw new \Exception('创建用户余额失败: ' . implode(', ', $balance->getErrorSummary(true)));
        }
        
        $value = SettingHelper::get('user.count') + rand(1, 10);
        SettingHelper::set('user.count', $value);
    });

    return $user; // 记得返回User实例,符合父类方法的返回规范
}

2. 关联加载的额外验证点

修复signup逻辑后,建议做以下验证确保关联正常:

  • 直接查看user_balance表,确认注册后的用户对应的user_id字段是否正确赋值。
  • 在需要调用balance->get()的地方,可主动加载关联,比如用$user->getBalance()->one()替代直接$user->balance,避免延迟加载的潜在问题。

3. 事务内的错误处理补充

你的事务中调用save()时没有处理失败场景,如果UserBalance因验证规则或数据库问题保存失败,事务会回滚但没有任何提示。添加错误抛出或日志记录,能帮助你快速定位后续问题。

总结

最核心的问题是重写signup方法时遗漏了父类的核心逻辑,导致User记录未正确创建,进而让UserBalance的关联关系完全无效。修复这个问题后,用户登录时$user->balance就能正确获取到对应记录,也就不会出现调用get()方法时的null报错了。

内容的提问来源于stack exchange,提问作者GaLana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:06:28