Alex
Alex

Reputation: 68406

Overloading properties and methods in PHP - what's the reason?

Is it a good idea to use overloading for solely cute-function-naming reasons? :)

For example:

echo $store->product->getPrice($currency);

echo $store->product('dog')->getPrice($currency);


The alternative without overloading would be:

if(!$store->product)
  $store->product = new Product();

 echo $store->product->getPrice($currency);

and

$product = new Product('dog');
echo $product->getPrice($currency);

I really like overloading because I can get nice API for my classes. But the downside is that overloaded stuff is 15x slower than calling properties / methods directly.

Is it ok to use overloading like this?

In my current application I'm not calling overloaded members more than 1000 times. And that shouldn't have that much impact on performance. Maybe an extra 0.1s, which considering that a site is usually generated in 0.5 - 1s is not so much

Upvotes: 5

Views: 2007

Answers (3)

hakre
hakre

Reputation: 197659

Is it a good idea to use overloading for solely cute-function-naming reasons? :)

No. I mean, it depends. :) Let's add some awesomeness and cuteness to our programming life:

$ordinary = new stdClass();
$ordinary->Caption = 'Hello';

class Awesome
{
   private $ordinary;
   public function __construct($ordinary) {
       $this->ordinary = (array) $ordinary;
   }
   public function __get($name) {
       $value = '';
       return $this->ordinary[$name];
   }
}

class Lovely extends Awesome
{
    public function __get($name)
    {
        return '<3 ' . parent::__get($name) . ' <3';
    }
}

I must admit, the example might be a bit over the top, but is shows something.

First of all, the assumption is that the API is for a class. So it starts with a very ordinary stdClass.

What the example then shows is that those magic functions can be used to overload or decorate something. Can, but must not. See the awesome API, it's just awesome by itself:

$awesome = new Awesome($ordinary);

echo $awesome->Caption, "\n"; # This caption is just awesome by itself!
# Hello

And then see the much more lovely API example:

$lovely = new Lovely($ordinary);

echo $lovely->Caption, "\n"; # This caption is lovely, hughs and kisses everyone!
# <3 Hello <3

So in this example, it's a good idea for Lovely but it's useless for Awesome, because Awesome is actually much more easy to obtain:

$awesome = $ordinary;

Which brings me to the point, that overloading in an API can only be useful up to a specific point. As Lovely shows, it can be used to decorate another (not much specified object), but it also shows that this is one-time only: Lovely already needs to know how to call Awesome to make use of it's functionality by using the (now not magic any longer) __get method:

    public function __get($name)
    {
        return '<3 ' . parent::__get($name) . ' <3';
    }

When you now consider that Awesome is your API, you can see that it prevented itself from being able to be overloaded easily from the other coderette that wants to make use of it.

So overloading can be fine in concrete code, and the API should not prevent that. But when the API is overloaded itself, things can turn out to be difficult.

Not only for coding, adding dynamics/magic makes things difficult to debug as well. So better stay clear for the APIs you create and provide more specific interfaces then just [] or ->. You can give things concrete names and that works well ;)

And it's much more lovely then:

echo $store->getObject('product')->getPrice($currency);

Upvotes: 3

Jeremy Harris
Jeremy Harris

Reputation: 24549

The payoff comes in benefits provided by adhering to object oriented design principles. The first example allows loose coupling by generating the product object from a factory. For more on OO design principles, see S.O.L.I.D. and G.R.A.S.P.

Upvotes: 1

KingCrunch
KingCrunch

Reputation: 131841

The downside of overloading is, that you must describe the "nice API" yourself, because documentation tools cannot understand, what you do inside your methods. Another point is, that it's often "too much magic": You make your code much harder to understand the more magic you implement.

On the other side I don't see any problem with your alternative. Its even cleaner in my eyes.

sidenote: Avoid using double underscores at the beginning of methods yourself, as long as you don't implement magic methods.

Upvotes: 3

Related Questions