Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get and set (private) property in PHP as in C# without using getter setter magic method overloading

Summary

Code sample:

Class People {
    // private property.
    private $name;

    // other methods not shown for simplicity.
}

Straight forward. Let me assume that $name is a PRIVATE class member (or property, variable, field, call it as you wish). Is there any way to do these in PHP:

$someone = new People();
$someone->name = $value;
$somevar = $someone->name;

WITHOUT using __get($name) and __set($name, $value).


Background

I needed to check the assigned $value, therefore I simply need a getter setter like this:

getName();
setName($value);

And NOT necessarily a getter setter magic method overloading like this:

__get($value); 
__set($value, $name);

That said, I simply need a getter setter. But that's NOT what I want. It just doesn't feel like object oriented, for people from static typed language such as C++ or C# might feel the same way as I do.

Is there any way to get and set a private property in PHP as in C# without using getter setter magic method overloading?


Update

Why Not Magic Method?

  1. There are rumors floating around the web that magic method is 10x slower then explicit getter setter method, I haven't tested it yet, but it's a good thing to keep in mind. (Figured out that it's not that slow, just 2x slower, see the benchmark result below)

  2. I have to stuff everything in one huge method if I use magic method rather then split them into different function for each property as in explicit getter setter. (This requirement might have been answered by ircmaxell)

Performance Overhead Benchmarking

I'm curious about performance overhead between using magic method and explicit getter setter, therefore I created my own benchmark for both method and hopefully it can be useful to anyone read this.

With magic method and method_exist:

(click here to see the code)

  • Getter costs 0.0004730224609375 second.
  • Setter costs 0.00014305114746094 second.

With explicit getter setter:

(click here to see the code)

  • Getter costs 0.00020718574523926 second.
  • Setter costs 7.9870223999023E-5 second (that's 0.00007xxx).

That said, both setter and getter with magic method and method exists justs costs 2x than the explicit getter setter. I think it's still acceptable to use it for a small and medium scale system.

like image 443
O.O Avatar asked Feb 07 '11 19:02

O.O


2 Answers

ReflectionClass is your salvation

I know it's too late for Hendra but i'm sure it will be helpfull for many others.

In PHP core we have a class named ReflectionClass wich can manipulate everything in an object scope including visibility of properties and methods.

It is in my opinion one of the best classes ever in PHP.

Let me show an example:

If you have an object with a private property and u want to modify it from outside

$reflection = new ReflectionClass($objectOfYourClass);
$prop = $reflection->getProperty("PrivatePropertyName");
$prop->setAccessible(true);
$prop->setValue($objectOfYourClass, "SOME VALUE");
$varFoo = $prop->getValue();

This same thing you can do with methods eighter;

I hope i could help;

like image 35
Guilherme Ferreira Avatar answered Sep 19 '22 00:09

Guilherme Ferreira


Nope.

However what's wrong with using __get and __set that act as dynamic proxies to getName() and setName($val) respectively? Something like:

public function __get($name) { 
    if (method_exists($this, 'get'.$name)) { 
        $method = 'get' . $name; 
        return $this->$method(); 
    } else { 
        throw new OutOfBoundsException('Member is not gettable');
    }
}

That way you're not stuffing everything into one monster method, but you still can use $foo->bar = 'baz'; syntax with private/protected member variables...

like image 52
ircmaxell Avatar answered Sep 21 '22 00:09

ircmaxell