This content originally appeared on DEV Community and was authored by david duymelinck
This is a rant about an article on freeCodeCamp named How Method Overloading Works in PHP.
It is more an emotional rant about creating readable and safe code rather than one where I angerly wave my fist at a cloud.
My freeCodeCamp article takeaways
Many languages have method overloading because it is a part of polymophism. And PHP provides it by using the __call method.
Zubair provides the code, addresses some use cases, so overall it is a good article.
The code
I'm biased because I find the __call method a garbage magic function. I only use it if there is no other way.
What i don't like about the code:
- mixed functionality, identifying the function overload and the actual code
- no consistent return
- no long term vision (what if you have ten or twenty methods you want to overload?)
You can argue it is an example to demonstrate overloading, and you are right.
I just want to cry when I see it, so lets continue to make me happy.
Fixing the code
class SampleClass
{
private function add2($numbers) {
return array_sum($numbers);
}
private function add3($numbers) {
return array_sum($numbers) > 10 ? 10 : array_sum($numbers);
}
public function __call($functionName, $arguments)
{
$count = count($arguments);
$methodName = $functionName . $count;
return method_exists(__CLASS__, $methodName) ? $this->{$methodName}($arguments) : NULL;
}
}
# The sample execution works
$sampleObject = new SampleClass;
echo $sampleObject->add(12, 12) . PHP_EOL; // Outputs 24
echo $sampleObject->add(12, 2, 6) . PHP_EOL; // Outputs 10
To clean up the __call method I used the arguments to create method names, and call the methods if they exist.
So now the only function of the __call method is to find methods in the class.
Nowhere in polymorphism it is mentioned that you can't use private functions to achieve overloading.
Another thing that makes me cry is not validating arguments. array_sum is a very forgiving function, but what if the code can't be so forgiving?
Preventing errors
class Numbers {
private array $collection = [];
public function __construct(...$nums) {
$this->collection = array_filter($nums, fn($num) => is_numeric($num));
}
public function toArray() {
return $this->collection;
}
}
class SampleClass
{
private function addOverload(Numbers $numbers) {
$arr = $numbers->toArray();
return match(count($arr)) {
2 => array_sum($arr),
3 => array_sum($arr) > 10 ? 10 : array_sum($arr)
};
}
private function callMethod($functionName, $arguments) {
$count = count($arguments);
$methodName = $functionName . $count;
if(method_exists(__CLASS__, $methodName) === FALSE) {
return NULL;
}
return $this->{$methodName}($arguments);
}
public function __call($functionName, $arguments)
{
return match($functionName) {
'add' => $this->addOverload($arguments[0]),
'default' => $this->callMethod($functionName, $arguments)
};
}
}
$sampleObject = new SampleClass;
$twentyfour = new Numbers(12, 12);
$ten = new Numbers(12, 2, 6);
echo $sampleObject->add($twentyfour) . PHP_EOL; // Outputs 24
echo $sampleObject->add($ten) . PHP_EOL; // outputs 10
I added a Numbers class to allow only numeric input. This change made me refactor the SampleClass. So there is now an addOverload method that switches the code based on the count.
When I look at the code I have now, there are a lot of lines that are just waste. I love the environment, so I'm going to reduce the waste.
Only in this case
# copy Numbers from previous example
class SampleClass2
{
public static function add(Numbers $numbers) {
$arr = $numbers->toArray();
return match(count($arr)) {
2 => array_sum($arr),
3 => array_sum($arr) > 10 ? 10 : array_sum($arr)
};
}
}
$twentyfour = new Numbers(12, 12);
$ten = new Numbers(12, 2, 6);
echo SampleClass2::add($twentyfour) . PHP_EOL; // Outputs 24
echo SampleClass2::add($ten) . PHP_EOL; // outputs 10
Now I am a happy camper. Bye bye __call method, no overloading because the code deviation is contained by the add method.
Conclusion
It is good to know the concept of method overloading, and use it when it is the best solution for the problem you are facing.
Just try to figure out if the code you write makes others and yourself happy in the future.
This content originally appeared on DEV Community and was authored by david duymelinck
david duymelinck | Sciencx (2023-05-18T09:29:27+00:00) PHP method overloading. Retrieved from https://www.scien.cx/2023/05/18/php-method-overloading/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.