Object instantiation

Hi all,

I’ll try to explain through a simple case:

I have a superclass: User

and a subclass: AdminUser

I do User::model()->findByPk(1), and expects a User object in return. But if $user->admin === true, it should return an AdminUser. How do i obtain that?

Thanks :)

Why do you need a separate class for an Admin? I would think it would be easier to have one user class with an admin property (and possibly better design).

I don’t think you can get a subclass from a superclass because the superclass has no clue about it’s children (since they can be anything). So if you really wanted to do something like that in a function you’d do:

if ($user->admin === true) return AdminUser::model()->findByPk(n);

else return $user;

But I’d really recommend just using User.


It was just an example, a more realistic scenario would be "categories".

These categories could then be extended into NewsCategories or ForumCategories with different logic, in order to minimize duplicate code, as all categories should have some shared functionality.

Another example, closer to the User example, could be to have a subclass called “OnlineUser” which extended User. Again duplicate code is eliminated as you don’t have to check in each method if the User is online first in the UserOnline class.

In the book PHP Objects, Patterns, and Practice they recommend that practice, and the AdminUser example is also described in there.

Your suggestion isn’t really good, while it would require overwriting a large amount of methods, for each “findBy*”.

you can see CActiveRecord::instantiate()

Thanks, that was exactly what i needed.

Is it possible to do overriding when using findBy? Like:


returns only categories with the respective type?


Do you mean using


Hmm… I don’t use that function, but it must be the same.

You’d probably want to use the AR scopes (see the manual for this).

You can then use something like:

$cat = Products::model()->catName1()->findAll(); // this will return all products with category as defined in scopes['catName1'];

$cat = Products::model()->catName2()->findAll(); // this will return all products with category as defined in scopes['catName2'];

Of course you can still add other selection criteria to the findAll function.