Question

Yii provides ORM based development which is OK for normal development. My question is, in my application there are many user related data like user info, user settings, user preferences and so on. Here user means the current logged in user.

If somewhere I need the background picture setting of the User I do the following

$user = User::model()->findByPk(Yii::app()->user->id);

$bgImage = $user->settings->backgroundImage;

I repeat the same thing on another places of the application wherever I need background image. Means again create instance of the $user which I don't think a good approach. So, is there a way by which we don't need to instantiate the user class again and again??? Remember I don't like the session approach.

Was it helpful?

Solution

Another approach is to use a singleton. In library code, do this:

public static function getUser() {
    static $user;

    if (!$user) {
        $user = User::model()->findByPk(Yii::app()->user->id);
    }

    return $user;
}

This can be called as many times as you like, but in a single web request the database call will be made only once.

Note that if Yii::app()->user->id might change inside a web request, it's worth having a static array indexed by that value instead - so the method caches correctly if your user logs on or off.

OTHER TIPS

The most common way to share related resources (classes, array...) is the Dependency Injection approach which really makes the class structure stable making dependencies as clear as possible. In this case I would suggest you to instantiate the user model once and pass it to every class that needs it via its constructor.

Considering your user model class to be UserModel and considering the constructor of the classes that depends on that one to be:

public function __construct(UserModel $user, ...) { ... }

you can then use it as:

$user = User::model()->findByPk(Yii::app()->user->id);
$bgImage = $user->settings->backgroundImage;

$dependentclass1 = new DependentClass1($user, ...);
...
$dependentclass2 = new DependentClass2($user, ...);
...
$dependentclass3 = new DependentClass3($user, ...);

About the suggested other answer:

It is right to know that there has been quite a few wars around the use of the Singleton (anti-)pattern that you should be aware of. Most of them has been discussed here on SO aswell. But you have to remember that: design patterns (like DI and Singleton) are just an option, not a requirement therefore you can fell free to use whatever have more sense to you, in your context.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top