tags:

views:

87

answers:

4

Hey SO community, I saw here: http://www.mustap.com/phpzone_post_203_setter-and-getter an argument for using a type of property handling common to C#, that is: If in C#, you can define a class like this:

public class Person 
{
    private string _name;
    public string Name
    {
        get{ return _name; }
        set{ _name = value; }
    }
}

then why is it wise or not to define a similar property in php like this:

public class Person
{
    private var $name;    

    public function Name() 
    {
        if(func_num_args() == 0) {    return $this->name;  } 
        else {$this->name = func_get_arg(0);  }
    }
}
+2  A: 

If you need to do some additional checking of the value to be set you may want to either define getFoo and setFoo methods or even better use property overloading. The latter will give the user the feeling of native property getting/setting. (The latter is what you do in C#. Only that there is only one method per class, not many.)

nikic
+1 only correct answer so far.
siride
+1, i'd also mention that overloading only emulates properties, but not replaces them. There is no real support for properties in php (yet).
stereofrog
+4  A: 

IMO, that doesn't look clean in PHP. It's like you're trying to jam the C# way into PHP because you think it's a nice feature of C#.

I see it as: In PHP, you're making a single function for doing two completely different things, which doesn't make sense. Meanwhile, in C#, it is single property, which is designed to be a single point of access for an object to be set/retrieved.

Ocelot20
My thoughts exactly. Think long and hard before trying to port features from one language to another. PHP deals with the drudgery of getter/setters via its magic methods. You may want to take a look at those instead.
Manos Dilaverakis
Yup, it violates the [single responsibility principal](http://en.wikipedia.org/wiki/Separation_of_concerns) (for routines instead of classes).
ircmaxell
i believe within my post that this method can be implemented as long as you do it properly
RobertPitt
+3  A: 

You're violating the Single Responsibility Principle by having one function be both a getter and a setter.

In c# it's just syntactic sugar, and is converted into a getter and setter, just like you should write it in php.

In fact, in c#, you can simplify it further by writing

public string Name { get; set; }

And the compiler will generate a private backing field, and your getter and setter functions for you.

Chad
jQuery (an excellent piece of software) does that all the time. `x.html(foo)` sets the value, `x.html()` returns.
stereofrog
It is a great piece of software, though, they made a conscious decision to break SRP, and only through strict adherence to their standard can this be done. All/most setters (methods called with an input) return a jQuery object, which allows for a chainable interface. And the getters are parameterless...sometimes. Things like `.attr('name')` is a getter, and `.attr('name', value)` is a setter. This is where this starts to get confusing. Because their functions do more than one thing depending on the parameters, the consumers of the library need to understand it. It could be confusing.
Chad
+1  A: 

it is wise, for example:

class Settings
{
    private $data = array();

    public function __call($key,$arguments = array())
    {
        return !count($arguments)) ? $this->data[$key] : $this->data[$key] = $arguments[0];
    }
}

Then doing

$Settings = new Settings();
$Settings->name('hello');
$Settings->foo('bar');

This now has created a unlimited amount of anonymous functions ready to use, this would usually be constructed using 2 methods, __get and __set this way you can define separation for methods and variables, example follows

class Settings
{
    private $data = array();

    public function __set($key,$val)
    {
        $this->data[$key] = $val;
    }
    public function __get($key)
    {
        return $this->data[$key];
    }
}

This would then allow you to set variables like so:

$Settings->foo = 'bar';

But you can go a little further then that and create a variable registry system:

so basically you can change the above class from Settings to VariableStorage and do the following:

class User extends VariableStorage{}
class Profile extends VariableStorage{}

And use like so:

$Profile = new Profile('Robert','Pitt',USER_PRIV_ADMIN);
$Profile->id = 56;
$Profile->userdata = $Database->GetUserData($Profile); //Reads $Profile->id

So that you only have to define the methods once and as long as you build your inherit structure to a good design it can work extremely well.

RobertPitt