Yii ActiveRecord查询获取到数据库行但父对象未填充数据如何解决
问题根源及修复方案
1. 重复声明公有同名字段导致属性读取异常
Yii ActiveRecord 底层依赖__get()、__set()魔术方法读写_attributes私有属性中存储的数据库数据。你在Admin类中主动声明了id、username、password、auth_key、access_token这些和数据库字段同名的公有属性后,PHP会优先读取你声明的公有属性的默认值,不会触发魔术方法去读取populateRecord已经写入_attributes的真实数据,所以会出现数据库返回了数据但对象属性为空的现象。
修复方案:删除所有你自行声明的、和数据库字段同名的公有属性即可,ActiveRecord会自动处理这些字段的读写逻辑。
2. 查询方法逻辑错误,存在多余实例化操作
你写的findByUsername、findIdentity、findIdentityByAccessToken三个方法逻辑完全写反,且存在多余实例化的问题:
// 原错误逻辑示例 $user = self::find()->where(["username" => $username])->one(); if ($user) { // 查到匹配用户反而返回null return null; } return new static($user); // one()返回的本身就是填充完成的实例,不需要二次实例化
同时findIdentityByAccessToken方法中的查询字段名写错,把数据库的access_token写成了accessToken会导致查询不到数据。
修复方案:直接修改三个查询方法如下:
public static function findIdentity($id) { return self::find()->where(["id" => $id])->one(); } public static function findIdentityByAccessToken($token, $type = null) { return self::find()->where(["access_token" => $token])->one(); } public static function findByUsername($username): ?Admin { return self::find()->where(["username" => $username])->one(); }
3. 密码验证方法逻辑错误
你当前的密码验证逻辑是把用户输入的密码加密后和数据库存储的哈希值比对,Yii的密码加密每次会生成随机盐,该逻辑永远无法验证通过。
修复方案:改用Yii自带的密码验证方法:
public function validatePassword($password): bool { return Yii::$app->getSecurity()->validatePassword($password, $this->password); }
修改完成以上三处问题后,ActiveRecord属性填充即可恢复正常。
内容的提问来源于stack exchange,提问作者vaso123
相关产品推荐
相关产品推荐

