wwwyii

wwwyii

这家伙有点懒,还没写个性签名!

  • 财富值605
  • 威望值30
  • 总积分1055

个人信息

  • 赞了回答

    asArray返回的是一个数组不是object,当然会提示 on a non-object

  • 回复了 的回答

    登录后,

    $id=Yii::$app->user->identity->id
    

    通过这个就可以获取到你用户模型的id了,然后通过User::findOne($id)就能获得你用户资料了,只是举例,原理就是这样哦~

    如我前面的回答,你需要在User中实现findIdentity($id)这个函数,返回一个User实例。和是否使用数据库保存没有关系。
    我看你使用的client是通过username/password来获取信息的,但是yii\web\user仅在session/cookie中保存了id信息。你需要么让client提供一个接口,通过id获取用户数据,或者将username/password也保存到session里面,以便在findIdentiy的时候获取这两个值,通过client获取信息。

  • 你的User需要实现findIdentity($id)这个函数,返回一个User实例。
    Yii里面的登录逻辑是这样的:在密码校验通过后,会调用Yii::$app->getUser->login($identify,$duration)来保存登录的用户的信息;以便下次访问直接获取用户的信息,不要再次输入密码等信息。
    问题1:如何保存用户的信息(/site/login)
    当然是保存到session和cookie中,这里和配置信息有关。yii\web\User.php中有两个参数$enableAutoLogin, $enableSession;
    $enableSession将用户信息保存在session中, $enableAutoLogin将信息进一步保存到cookie中,参考login的一段代码

        if ($identity) {
                $session->set($this->idParam, $identity->getId());
                if ($this->authTimeout !== null) {
                    $session->set($this->authTimeoutParam, time() + $this->authTimeout);
                }
                if ($this->absoluteAuthTimeout !== null) {
                    $session->set($this->absoluteAuthTimeoutParam, time() + $this->absoluteAuthTimeout);
                }
                if ($duration > 0 && $this->enableAutoLogin) {
                    $this->sendIdentityCookie($identity, $duration);
                }
    

    问题2, 用户下次访问的时候,如何获取用户的信息(访问/site/index)
    既然在问题1中保存到了session/cookie中,那么自然要从这个里面取出来。我们访问用户的信息的时候一般采用的方式是Yii::$app->getUser->getIdentity(),这个函数的功能就是从session/cookie中取出用户的数据并重构identiy实例。其中重构的关键代码如下,里面的 $class::findIdentity($id)使用来重新构建identity实例的,你的User恰好没有实现这个,所以导致啥也没有啊。

       protected function renewAuthStatus()
        {
            $session = Yii::$app->getSession();
            $id = $session->getHasSessionId() || $session->getIsActive() ? $session->get($this->idParam) : null;
    
            if ($id === null) {
                $identity = null;
            } else {
                /* @var $class IdentityInterface */
                $class = $this->identityClass;
              **_  $identity = $class::findIdentity($id);_**
            }
    
            $this->setIdentity($identity);
    
  • 回复了 的回答

    附上一段代码,是在insert/update之前调用的validate函数,如下;注意其中的

    if ($attributeNames === null) {
                $attributeNames = $this->activeAttributes();
            }
    

    这里的activeAttributes是当前的scenario所包含的属性,即 ['username', 'email', 'status'],接下来的校验之针对这几个属性做教研,不会针对password做校验。

    public function validate($attributeNames = null, $clearErrors = true)
        {
            if ($clearErrors) {
                $this->clearErrors();
            }
    
            if (!$this->beforeValidate()) {
                return false;
            }
    
            $scenarios = $this->scenarios();
            $scenario = $this->getScenario();
            if (!isset($scenarios[$scenario])) {
                throw new InvalidParamException("Unknown scenario: $scenario");
            }
    
            if ($attributeNames === null) {
                $attributeNames = $this->activeAttributes();
            }
    
            foreach ($this->getActiveValidators() as $validator) {
                $validator->validateAttributes($this, $attributeNames);
            }
            $this->afterValidate();
    
            return !$this->hasErrors();
        }
    

    其中 $validator->validateAttributes($this, $attributeNames);是获取当前scneriao的所有validator,然后利用这些validator对scenario包含的属性进行校验;根据你的设置,当前的validator是包含['password','check']的,但是validator检验属性的时候是要检验validator指定的属性(password)和scnario属性(email,username...)的交集;所以实际上该validator啥也没做。
    修改一下update需要检验的属性就可以了:$scenarios['update'] = ['username', 'email', 'status','password'];这样update场景下会执行pssword check和min validator


    如果你是要在model中增加辅助属性,不要操作attributes函数,直接在model里面声明一个属性就可以了,这个属性和其他的attribute用法一样,但是在操作数据库的时候不会使用该属性。例如

    public UserModel extends extends ActiveRecord implements IdentityInterface{
    
        public $confirmPassword;
        public $newPassword;
        public $password;
        //以上三个属性你可以任意使用,但是和数据库没有任何关系,在更新数据表的时候不会涉及。
    
    
        public function rules(){
    
         // change password
                [['newPassword', 'confirmPassword'], 'required'],
                [['newPassword', 'confirmPassword'], 'string', 'min' => 8],
                [['confirmPassword'], 'compare', 'compareAttribute' => 'newPassword'],
         }
    }
    
  • 回复了 的回答

    最好是使用php_ini来设置这些属性,不然部署一次环境就要修改一下环境,容易出错。


    可以,也可以在Application构建之前设置。把需要设置的参数加入到params文件定义中,然后取相应的值进行设置。

  • 最好是使用php_ini来设置这些属性,不然部署一次环境就要修改一下环境,容易出错。

  • 附上一段代码,是在insert/update之前调用的validate函数,如下;注意其中的

    if ($attributeNames === null) {
                $attributeNames = $this->activeAttributes();
            }
    

    这里的activeAttributes是当前的scenario所包含的属性,即 ['username', 'email', 'status'],接下来的校验之针对这几个属性做教研,不会针对password做校验。

    public function validate($attributeNames = null, $clearErrors = true)
        {
            if ($clearErrors) {
                $this->clearErrors();
            }
    
            if (!$this->beforeValidate()) {
                return false;
            }
    
            $scenarios = $this->scenarios();
            $scenario = $this->getScenario();
            if (!isset($scenarios[$scenario])) {
                throw new InvalidParamException("Unknown scenario: $scenario");
            }
    
            if ($attributeNames === null) {
                $attributeNames = $this->activeAttributes();
            }
    
            foreach ($this->getActiveValidators() as $validator) {
                $validator->validateAttributes($this, $attributeNames);
            }
            $this->afterValidate();
    
            return !$this->hasErrors();
        }
    

    其中 $validator->validateAttributes($this, $attributeNames);是获取当前scneriao的所有validator,然后利用这些validator对scenario包含的属性进行校验;根据你的设置,当前的validator是包含['password','check']的,但是validator检验属性的时候是要检验validator指定的属性(password)和scnario属性(email,username...)的交集;所以实际上该validator啥也没做。
    修改一下update需要检验的属性就可以了:$scenarios['update'] = ['username', 'email', 'status','password'];这样update场景下会执行pssword check和min validator

  • 赞了回复

    坚决不推荐第一种方法,我之前试过,TMD后期维护是个大工程

  • 赞了回复

    如果每个城市的业务彼此独立,同时,城市之间的业务都非常相似,建议直接分库,这样便于后期根据城市的特点各自单独维护。

    建议你采用同一份代码,部署同一个服务器,根据不同的子域名调用不同的数据库。等后期业务成长起来了,再单独部署。

经理 等级规则
1055/2000
资料完整度
10/100
用户活跃度
0/100

Ta的关注

1

Ta的粉丝

1

Ta的访客

4