Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: Static method in Class vs Global function in Namespace?

What's the difference between creating a Global function in a Namespace (and calling it from the global namespace):

<?php
namespace MyNamespace  {
    function MyFunction($x, $y)  {
        return $x + $y;
    }
}

namespace {  //global code... in a new file
   var_dump(MyNamespace\MyFunction(1,2));
}

and creating a static class method, and calling from the global Namespace?:

<?php
class MyClass  {
    public static function MyFunction($x, $y)  {
        return $x + $y;
    }
}

var_dump(MyClass::MyFunction(1,2));

Is there any reason to prefer one method over the other?

like image 327
mcmurphy Avatar asked Jan 19 '17 18:01

mcmurphy


2 Answers

Is there any reason to prefer one method over the other?

(below assumes you're asking/referring to a difference between a static class method and a function in a namespace)

Historically (before namespaces arrived), people were forced to use classes with static functions to not pollute a global namespace. This is one of the reasons you're likely to encounter this method more often.

You might prefer to use a static method if you need access to class's data or if you think of leaving a door to overriding them in descendant classes (the so-called 'flexibility and functionality' by some).

You might prefer a namespaced function when all you want is ...uh, ahem... a function. Think of some util, functional or collections functions like compose/partial, retry , filter/map/some/every etc. You are probably not expecting this to be overwritten in a child class, right? Neither it need access to some static class member.

There is one particular annoying problem with (namespaced) functions though, that classes don't suffer from. And it's autoloading. To put it short, there is no way to autoload a function at the moment. And this is another reason you'd likely encounter classes with static methods (when they don't necessarily need to be) more often in practice.

like image 178
DCrystal Avatar answered Oct 12 '22 22:10

DCrystal


The primary difference is the global namespace can only ever have one function named MyFunction.

Using namespaces, each namespace can have it's own copy of MyFunction. This allows you to flexibility to create a common API without having to come up with clever names.

For example:

namespace Mail {
    public static function send() {
        // Send Mail
    }
}

namespace SMS {
    public static function send() {
        // Send Text Message
    }
}

That wouldn't be possible with a single global namespace. But now you have a predictable interface to call Mail\send() or SMS\send().

For classes, the ability to create these contracts works much better than functions within a namespace, because you get the ability to build interfaces and use abstraction.

For example:

abstract class Mail {
    public static function send() {
        // Create empty implementation (have to do this because it is static)
    };
}

class MailChimp extends Mail {
    public static function send() {
        // Send Mail
    }
}

class MailGun extends Mail {
    public static function send() {
        // Send Mail
    }
}

With that, we can now namespace things under "Mail", but also effectively under the specific implementations of mail, and keep the common send() API we've come to know and love.

Is there any reason to prefer one method over the other?

Either will work. You just get more functionality and flexibility when dealing with classes.

like image 29
Jeremy Harris Avatar answered Oct 13 '22 00:10

Jeremy Harris