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);
product
will call __call, then __callObject('product', ...)...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
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.
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.
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.
Overloading is the creation of more than one procedure, instance constructor, or property in a class with the same name but different argument types.
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);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With