Dynamic Getter/setter Methods Instead Of Properties

I love Yii, I think it’s a fantastic framework. When I made the move from Code Igniter I wanted to go back and redo previous projects in Yii because it was more fun to code with.

What I don’t understand is why Yii doesn’t utilize functions instead of properties when accessing model data/relations. I don’t believe it’s as overloading friendly as it could be. If I used $model->created I get a string which is a MySQL DateTime representation of a time. But say I wanted it to return a DateTime object? I’d have to go in and overload some functions which can quickly get messy. I’d much rather be able to just go in and overload $model->getCreated(); to do what i want it to do.

I find $model->getCreated(); both easier and cleaner to overload than $model->created.

Look in CComponent from which CModel and thus CActiveRecord is derived.

If you do, then you know that Yii uses __get and __set overloading.

So what you need to do, is overload getGreated in your model. ;)

From the docs:


 * CComponent is the base class for all components.


 * CComponent implements the protocol of defining, using properties and events.


 * A property is defined by a getter method, and/or a setter method.

 * Properties can be accessed in the way like accessing normal object members.

 * Reading or writing a property will cause the invocation of the corresponding

 * getter or setter method, e.g

 * <pre>

 * $a=$component->text;     // equivalent to $a=$component->getText();

 * $component->text='abc';  // equivalent to $component->setText('abc');

 * </pre>

 * The signatures of getter and setter methods are as follows,

 * <pre>

 * // getter, defines a readable property 'text'

 * public function getText() { ... }

 * // setter, defines a writable property 'text' with $value to be set to the property

 * public function setText($value) { ... }

 * </pre>

Just overload it, and the rest of your team just use the property.

And probably wonder why $model->created now returns a Date object instead of a string. :P

It doesn’t appear to be functional on attributes. In my application… $carrier->created returns a MySQL DateTime whereas $carriet->getCreated(); throws a … “do not have a method or closure named “getCreated”.”

It seems that you may have a typo there if you brought this from your code.

haha, of course. I didn’t have a typo in my code, just in this forum post. I just did it again to double check and be sure that was the case.

This won’t work because the property “created” already exists

create getCreatedOn() and $carrier->createdOn will return the result of $carrier->getCreatedOn()

The CActiveRecord’s magic __get() function will first check if an attribute exists else the value of $carrier->created wont be accessible any more.

In that case, I would think it would be better for Yii to store entity data within a $data property instead of just object properties as it is today.

If ‘created’ is a column in your database table, you can’t overload it with a getCreated() method.

However, what you should do, is create a method called getCreatedObject().

You can then access that method by using $model->createdObject;

If we have "CREATED_DATE" a mysql table column then how is it possible to achieve $model->setCreatedDate() and $model->setCreatedDate() function should work.

I do not want to create getter & setter methods for all the columns of a table. Mostly all the column names includes underscore & all are in CAPS.

In your case it is probably a good idea to create the actual method and a phpDoc block for it. Magic is not auto-completed unless you do the phpDoc. And cause you have to do the phpDoc anyway - why not write the getter you need?

Performance wise that is a good decision too - __get/__set/__call are not free you know…