PHP method overloading

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 ta…


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


Print Share Comment Cite Upload Translate Updates
APA

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/

MLA
" » PHP method overloading." david duymelinck | Sciencx - Thursday May 18, 2023, https://www.scien.cx/2023/05/18/php-method-overloading/
HARVARD
david duymelinck | Sciencx Thursday May 18, 2023 » PHP method overloading., viewed ,<https://www.scien.cx/2023/05/18/php-method-overloading/>
VANCOUVER
david duymelinck | Sciencx - » PHP method overloading. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2023/05/18/php-method-overloading/
CHICAGO
" » PHP method overloading." david duymelinck | Sciencx - Accessed . https://www.scien.cx/2023/05/18/php-method-overloading/
IEEE
" » PHP method overloading." david duymelinck | Sciencx [Online]. Available: https://www.scien.cx/2023/05/18/php-method-overloading/. [Accessed: ]
rf:citation
» PHP method overloading | david duymelinck | Sciencx | 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.

You must be logged in to translate posts. Please log in or register.