anon
anon

Reputation:

Handling PHP properties like those in C# (getter & setter)

I have been doing some research over time and wanted to know if using properties in a PHP class can be done like C#, I have found these questions which game some good answers and pointers, but didn't help me really:

Although, as I said, these give good answers, I still can't make up my mind on these, for example, I want to be able to do something such as:

class Foo 
{
    public $bar
    {
        get { return $this->bar; }
        set { $this->bar = value; }
    }
}

But I am unable to!

What is the best way to do this within the constraints of PHP?

The kind of thing I have been able to come up with is this:

class user
{
    private static $link;
    private static $init;

    private function __construct ()
    {
        global $link;
        static::$link = $link;
    }

    public static function __INIT__ ()
    {
        return static::$init = (null === static::$init ? new self() : static::$init);
    }

    public static $username;

    public function username( $value = '' )
    {
        if ( $value == '' || empty ( $value ) || !$value )
            return static::$username;
        else
            static::$username = $value;
    }
}

Upvotes: 4

Views: 2567

Answers (2)

S.Pols
S.Pols

Reputation: 3434

Maybe you need to think if it's really neccessary. It is just a shorthand to write getters and setters.

private String _name;

public String Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
    }
}

Has exactly the same function as:

private $_name;

public function getName()
{
    return $_name;
}

public function setName($name)
{
    $_name = $name;
}

There is only a difference in the call:

C#  : Object.Name = "This is my Name";
PHP : Object->setName ("This is my Name");

If you really preffer for the C# syntax (which in my opinion is just a habit), i think Flosculus's answer is the only option. It isn't that complex if you realise what the code does. For information:

__set() is run when writing data to inaccessible properties.
__get() is utilized for reading data from inaccessible properties.

In this example furColor is inaccessible since it's a protected variable.

So what happens here $cat->furColor = 'black.

  • furColor is inaccessible so magic method __set is calling.
  • It creates a setter in GetterSetterExample named setFurColor and check if it exists.
  • Yeah it does exist, because Cat implemented it.
  • setFurColor is called and variable is set.

In the final also this code is doing the exact same as the general getters and setters from the example above. It's just a 'workaround' to simulate C#'s properties. So to come back on my first question of this answer, is it neccessary? In my opinion it isn't. PHP doesn't support properties, so it has no clear meaning why you would try to simulate it. General getters and setters are the way to go and as shown in my examples it does the exact same thing. Magic methods are slow, and good luck if you want to do this in a type safing way. The sample code of Flosculus isn't complex, but this approuch can become (unneccessary) complex.

Upvotes: 3

Flosculus
Flosculus

Reputation: 6956

This is what PHP magic methods are for. They allow you to dynamically set properties through a mediator method. Here, let me show you an example:

abstract class GetterSetterExample
{
    public function __get($name)
    {
        $method = sprintf('get%s', ucfirst($name));

        if (!method_exists($this, $method)) {
            throw new Exception();
        }

        return $this->$method();
    }

    public function __set($name, $v)
    {
        $method = sprintf('set%s', ucfirst($name));

        if (!method_exists($this, $method)) {
            throw new Exception();
        }

        $this->$method($v);
    }
}

class Cat extends GetterSetterExample
{
    protected $furColor;

    protected function getFurColor()
    {
        return $this->furColor;
    }

    protected function setFurColor($v)
    {
        $this->furColor = $v;
    }
}

$cat = new Cat();
$cat->furColor = 'black';

Yeah... it terrifies me as well.

This is why most people are content with using methods like the ones in Cat, but public. Apparently there is discussion on adding "real" getters and setters, but there appears to be a lot of conflict between those who hate them for concerns of readability, semantics and principle...

Upvotes: 4

Related Questions