Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);

  • product will call __get then __getObject('product') which does the magik stuff and returns the current product that's being viewed as an object (it is instantiated if it's the first call)

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

  • here product will call __call, then __callObject('product', ...)...


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

like image 948
Alex Avatar asked Jan 03 '12 12:01

Alex


People also ask

What is Property Overloading in PHP?

Property Overloading: PHP property overloading is used to create dynamic properties in the object context. For creating these properties no separate line of code is needed. A property associated with a class instance, and if it is not declared within the scope of the class, it is considered as overloaded property.

Is there method overloading in PHP?

To achieve method overloading in PHP, we have to utilize PHP's magic methods __call() to achieve method overloading. __call(): In PHP, If a class executes __call(), and if an object of that class is called with a method that doesn't exist then, __call() is called instead of that method.

Why does PHP not support method overloading?

You cannot overload PHP functions. Function signatures are based only on their names and do not include argument lists, so you cannot have two functions with the same name. Class method overloading is different in PHP than in many other languages. PHP uses the same word but it describes a different pattern.

What is Property overloading?

Overloading is the creation of more than one procedure, instance constructor, or property in a class with the same name but different argument types.


2 Answers

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);
like image 116
hakre Avatar answered Nov 15 '22 13:11

hakre


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.

like image 27
KingCrunch Avatar answered Nov 15 '22 11:11

KingCrunch