Inheritance In Behaviors - Creating Function Aliases?

I’ve created a behavior for handling group of properties for a given model (such as abilities or preferences for User), usually represented by a long list of checkboxes.

The way I’ve done this is using single table inheritance, with a database table called ItemProperties, and then a class structure of e.g.

abstract class ItemProperty{

/*Single table inheritance parent class */

function getAvailableProperties();

function getProperty();

function setProperty();


class UserPreference extends ItemProperty();

class UserAbility extends ItemProperty();

(I’ve used child classes because they all have a list of different available properties)

Each instance of ItemProperty represents a single property (e.g. a checkbox)

I then use behaviors attached to the Item to handle groups of Properties.


class ItemPropertyGroup extends CBehavior


   /*the class the property applies to*/

   public $propertyClass;

   function getPropertyList()


       /*gets a property list ready for creating a checkbox*/



class PreferencesGroup extends ItemPropertyGroup



    public $propertyClass = 'UserPreference'


    public function getPreferenceList()


          return $this->getPropertyList();



class AbilitiesGroup extends ItemPropertyGroup



    public $propertyClass = 'UserAbility'


    public function getAbilityList()


          return $this->getPropertyList();



and then in my User class (for example), adding

class User extends CActiveRecord




     return array (

           'UserPreferences' => array (

            'class'=> 'ext.PreferencesGroup'),

            'UserAbilities' => array (

           'class'=> 'ext.AbilitiesGroup'),






Which works fine, except every time I create a new set of properties, I have to create a new child class of ItemPropertyGroup with alias functions. The reason I did this was because as far as I’m aware, if I just use the same class and attach it several times over to my User model, the getPropertyList() function will just overwrite itself.

Is this correct? Can you recommend a more elegant way to achieve the same outcome?

Hi IainG,

This wiki may help you: Understanding Virtual Attributes and get/set methods.

Please post again if you need clarifications. Good luck!

What you can do is:

// same as $user->getPreferenceList();


// same as $user->getAbilityList();


This way, you wouldn’t need aliases. But honestly, I’m not sure if this is any better than the aliases…

@Rodrigo, thanks… what I’m really after are Virtual Functions rather than Virtual attributes.

@Ben… I’d not thought of method chaining. That might be a better way to handle it.

In this case, here are some inspiration for you:

  • PHP Magic Methods

  • _call

Those were what I’m after, but it looks like you can’t use the in Yii because that’s how behaviors work:

I’ve refactored my extension to use a single ItemProperty class and a single ItemPropertyGroup behavior.

Instead of using subclasses I’m using a private $_type field, and using a setPropertyType($type) function with method chaining as Ben suggested.

So now I just do $User->setPropertyType($type)->methodName().

The has the advantage that I don’t need to create a new subclass for each category, I can just do all my configuration in a separate config array which I include() in main.config.

Thanks for your help both!