There is a coding pattern that I see (and have used) in PHP code that defines generic methods on a class for setting and getting properties.
function set($name, $value); function get($name);Google code search for examples
Some times there are some ancillary methods to deal with unsetting, checking for existence, setting via an array, or dealing with references in PHP 4. They can really clutter up the definition of a class. That’s not good. All this code is fairly standard, too, but it gets duplicated on every class that does this. That’s not good, either.
Oh, I’ll solve this problem by making a base class, some may say. Wrong. This a very feeble reason to spend your one shot at inheritance. Trust me, I know, I’ve done it.
I think the idea is to make the class extensible. But PHP is really ok with just setting new properties on a class.
$obj->foo = 'bar';
So why not just do this?
Another variation of this pattern is to use setXXX($name, $value) or setYYY($name, $value) methods. This happens alot with “options” or “vars” or “properties.” It also happens on request wrapper classes. To me this looks like there is an object here just begging to get out for each XXX and YYY.
$obj->xxx->prop = 'foo'; $obj->yyy->prop = 'foo'; $obj->zzz->prop = 'foo';
This eliminates a slew of property manipulation methods and leaves the original class free to implement its true purpose. Methods of the form getXXX($name) and setXXX($name, $value) should be the solution of last resort.
Since I’ve started eliminating these in my own code in favor of direct properties, intermediate objects or __set and __get, I feel I’ve seen nothing but positive results. Try it. You may like it, too. Let your properties be properties.
UPDATE:
From reading the comments, I think there was some confusion about what I meant in this post. I am not talking about using naked properties instead of accessor methods. I’m not talking about accessor methods at all in this post. A specific accessor method, such as
$obj->getFoo()
where the name of the property is part of the method name is very different than
$obj->get('foo');
Where you pass the name of the property as a string parameter. Its only the latter pattern, where the property name is an actual parameter to the method, that I am talking about in this post and that I think should generally be refactored.
IIRC, the original reasoning behind the use of get and set methods was to encapsulate the logic involved in obtaining or storing data in case that logic ever had to be changed, more commonly such that it was more complex. Granted, __get and __set are available in PHP 5, but those can build up clutter over time as classes grow. Seems better to just head it off at the pass by having the methods to start with. Granted, it makes the classes a little larger, but I think I’d rather have that than have to refactor classes further down the road because they became too cumbersome to maintain. Even in cases where all these methods do is get or set a class property to start with, it’s better to be consistent. Such cases, even though it seems unlikely they will ever change, can always come back and surprise you.
I prefer using direct property access myself. However, in most of my real-world scenarios, I find myself writing accessors ((set|get)*()) as sooner or later I end up extending the class and adding business logic surrounding the property.
For instance, I may need to validate that a value to which I am setting a property follows particular rules — if I allow direct access to the property, another programmer could bypass these checks, leading to errors and potential data corruption.
Also, using an accessor to retrieve a property means I can later extend the accessor to do some logic prior to returning the property. As an example, a call to getResponse() could be modified to instantiate a response object if none is already defined in the object — much more useful than getting a null value. Or I might want to check that valid view paths are registered before I return a view — throwing an exception if not.
Basically, accessors have their place, particular when working with classes meant for extending or consumption by third parties.
I’m strongly in favour of getFoo() / setFoo() because I think it’s important to have a well-defined interface. Named getters/setters might explain the intent of the object a bit better, may accumulate additional logic as mentioned above, and can be mocked in tests. It’s surely one of the fundamentals of OOP: you can’t do anything with an object except via an interface?
Just to be clear, I’m not against accessor methods. However, a specific accessor method, such as
where the name of the property is part of the method name is very different than
Where you pass the name of the property as a string parameter. Its only the latter pattern that I am talking about in this post and that I think should generally be avoided.
I don’t understand what you’re doing.
If you make a class that’s extensible then you’re making a base class, or am i wrong? Do you mean that you use the possibility of PHP to set new (not existing) properties of a class?
What is setXXX? Are you setting a property xxx of a class, is xxx an existing property or is it a new property, is xxx an object?
How do you use it, $obj->setXXX( ‘prop’ , ‘foo’ ) ; ?
the get/set pattern is that what i hate.
its slow (function calls are slow)
its obfuscating the code
its so javaesk
its ignoring the fact that there are the __get etc. methods
so another one saying NO to the get/set schema
i am undecided if magic methods are a good thing. i am using them but they get quite messy if inheritance comes into play. mostly i end up writing protected setters to encapsulate them better and make sure that inheriting classes have a well defined interface to override a setter.
how do you handle inheritance with your magic methods?
Jeff Moore’s Blog: Let Your Properties be Properties
[...] a recent post to his blog, Jeff Moore advocates the philosophy that, in your OOP application development, you [...]
I understand the logic to this, but it’s going to be more tedious as you get into larger applications with many classes vars and (of course) properties… For every var to be treated individually like that may be daunting.
If you’re writing an application that’s just going to sit and function (little to no maintenance), then I don’t know how worthwhile it’d be to use this method. Though for larger applications that undergo maintenance and upgrading/updating, I think that this is very acceptable, and might help avoid problems with making edits down the road.
[...] I stumbled upon a weblog post of Jeff Moore on the way properties of objects should be accessed in PHP. Accidently, I thought a little about this problem myself last week because I’m working on a [...]
How would you program this to an interface.
Getters and setters are conventions, not interface implementations, or am I missing your point?
Hi, you can have all the getXXX/setXXX methods without declaring them, just using the magic function __call and cutting the “get” or “set” part from the name of the method invoked and doing the $obj->XXX = value internally in __call. That’s what I do in my projects.
cheers,
Pablo.