How to update cookie when [user] state changed

Yii::app()->user is a good staff, we could used it to store user base information, and also could add more information to it (see this wiki). When cookie-based authentication is enabled,these persistent information will be stored in cookie.

The problem is when these information are changed, we could update these session values with setState(), but how to update cookie values when cookie-based authentication is enabled. The method of save cookie:saveToCookie() in CWebUser class is a protected method,I can’t call it. I used try to write a same name cookie to override the old cookie,but it’s complex and failed last.

There are maybe an alternative solution is write a new WebUser Class to extend CWebUser, remove cookie use "Yii::app()->getRequest()->getCookies()->remove($this->getStateKeyPrefix());" first, then call saveToCookie() to update the cookie values.

I think yii should native support this implementation or anyone got a better solution?

When cookie-based login is enabled, Yii saves to the cookie only states related to CUserIdentity class and states which set by CWebUser::setState() are always saved to the session.

See related discussion here.

So I think you whether need to extend CWebUser and save all states to the cookie if cookie-based login is enabled or implicitly save state to the cookie using Yii::app()->getRequest()->getCookies()->add().

Or maybe you just need use CWebUser object instead of CUserIdentity to save states to the session instead of cookie.

Yes, I want to use CUserIdentity::setState() to save more user information,and expect to store these information to the cookie, which could reduce a database read(Of course,cookie size should be keep more small for performance).But cookie saving operation is implemented with protected method in CWebUser class, we can’t update the cookie values.

Implicitly save state to the cookie using Yii::app()->getRequest()->getCookies()->add() may be a direct and simple solution,but I think it’s duplicate and wasteful which store another user information to a new cookie. And sometimes, the built-in state ‘username’ also could be changed by user(eg. username use as a nickname or display name in some web site, user can changed it anytime), when user come back next time with cookie login, it still display the old name until user logout and login again.

So, except extend CWebUser class, any good solution ? Or yii should support it natively.

As I understand, CUserIdentity is meant to be used during login process only.

So I think you should extend CWebUser and implement there some methods to get / set appropriate user data.

You can store this data using CWebUser::setState() to the session and reread data from the database if session is expired. Something like this:




class AppUser extends CWebUser {

    

   public function setUsername($name) { 

      $this->setState('username', $name);

   }


   public function getUsername() {

      if ($this->hasState('username') {    

          return $this->getState('username');

      }

      //no state available

      //reread data from db and call setState()

      //return data from db

   }

}


//using somewhere

echo Yii::app()->user->username;




You also can use memory cache to store user data instead of session.