views:

82

answers:

3

I'm looking for advice/experience on using public variables vs private variables with accessor methods in php.

eg $obj->foo = 'a'; echo $obj->foo;

vs $obj->setFoo('a'); echo $obj->getFoo();

What I like about public variables is the shorter syntax - just seems less work to use. I understand that it could make refactoring more difficult later, but I've never experienced it (meaning, sometimes the design changes - but usually the accessor methods would need to be changed any.)

The other option is to store the variables in an array and use magic methods (_get/_set) to access them - then I have the ease of use of public variables with the ability to refactor or accessor methods.

Any experience or references of what people do in the php world.

And for anyone that hold the accessor method are the best way, is there a valid need/use for public variables?

+3  A: 

Yes, accessor methods are an overhead, although the syntax for using setters/getters is just as clean as direct access of public properties... slightly more wordy, but just as clean.

Biggest benefit of accessor methods is that you can use your set method to validate values and reject inappropriate values (e.g. trying to set a property that should always be an integer to a string or an array)... but this verification only works if external code can't access the property directly.

Second benefit if your code has related properties, where a change to property A requires a change to property B as well... if the properties are public, you can't control (or enforce) this.

Using set methods allows you to implement fluent interface, or to cleaner code for instances like:

echo $obj->setFoo('a');

instead of

$obj->setFoo('a'); echo $obj->getFoo();

if you include a return in your set method

Mark Baker
I would think that $obj->setFoo('a') would be better to return $obj so I could chain it.
Yehosef
what about just using $obj->foo() where $obj->foo() is the getter and $obj->foo('sdf') is the setter? this approach is use in jquery an seems to result in a relatively clean interface
Yehosef
@Yehosef - Personally, I'd always return the object from a setter myself to build a fluent (chained) interface, I was simply suggesting alternative options... and there's nothing to stop people using a single get/set method (whether it has get/set in the method name is merely a convention) that identifies whether it's a getter or setter based on whether an argument is passed or not. My argument is reasons to use accessor methods rather than direct access to public properties... the exact nuances of how those methods are implemented is another matter entirely.
Mark Baker
@Mark - what about accomplishing this using the magic get/set methods? This provides a fast way to get started/prototype because the methods directly match the underlying structure using a generic handler, but you can also change the get/set to act differently if the implementation needs to change. my main concern with the the getter/setter approach is just the overhead of writing the code in a rapid-development setting.
Yehosef
It's perfectly feasible using the magic _get and _set methods: I did some tests a couple of years ago when I found that the magic methods were fractionally slower, but the class memory footprint was reduced. __But__ (in my opinion) the code is more easily documented (using PHPDocumentor) when using explicit get/set methods... particularly useful when writing OSS libraries, or for autocompletion when coding within an IDE. I'd imagine that there are also IDEs/tools that will automate creating stub getter/setter methods when fed a set of properties (though I couldn't give you any references).
Mark Baker
thanks for the input - it seems what might be a good balance between rapid development and future-proofing would be to use $obj->foo() and to use _call to map that to $obj->foo - I can get started with minimal overhead but when I find that $obj->foo really needs to be $obj->bar, I can add a function called $obj->foo() to get/set $obj->bar. Then if/when there is time later to deal with documentation, all the functions can be filled in.
Yehosef
A: 

Getters/Setters arose in Java. They have no place in scripting languages, hence they are frowned upon in e.g. Python and Javascript. They make the API more combersome.

As you already know, you can use __get to wrap variable access. This is advisable in scripting languages. It allows you to e.g. validate types in a central location, you don't have duplicated code in multiple setters/getters.

 function __set($name, $value) {
     if (gettype($value) == $this->_types[$name]) {
          $this->_vars[$name] = $value;
     }
 }   // instead of twenty methods checking the type

It's a code smell to implement hollow getters/setters to have enterprisey-looking code. And it's also inadvisable to have getters/setters with side-effects. Always use real methods / messages for complex object operations.

mario
It's an interesting distinction to scripting languages - do you have links that refer to this? Any what do you mean having getters/setters with side effects?
Yehosef
A: 

setters and getters are always the best option because they provide more stability for validation / sanitization.

public function __call($name,$params = array())
{
    if(strstr('set',$name))
    {
    }//returns

    if(strstr('get',$name))
    {
    }//Returns

    if(strstr('run',$name))
    {
    }//Returns
}
RobertPitt