Search code examples
phpoopmagic-methods

PHP 5.3 Magic Method __invoke


This topic expands on When do/should I use __construct(), __get(), __set(), and __call() in PHP? which talks about the __construct, __get and __set magic methods.

As of PHP 5.3 there is a new Magic Method called __invoke. The __invoke method is called when a script tries to call an object as a function.

Now on research I have done for this method, people liken it to the Java method .run() - see Interface Runnable.

Having thought long and hard about this I can't think of any reason why you would call $obj(); as opposed to $obj->function();

Even if you were iterating over an array of objects, you would still know the main function name that you would want to run.

So is the __invoke magic method another example of 'just because you can, doesn't mean you should' shortcut in PHP, or are there cases where this would actually be the right thing to do?


Solution

  • This answer is slightly outdated for being written in 2009. Please take it with a grain of salt.

    PHP does not allow the passing of function pointers like other languages. Functions are not first class in PHP. Functions being first class mainly means that you can save a function to a variable, and pass it around and execute it at any time.

    The __invoke method is a way that PHP can accommodate pseudo-first-class functions.

    The __invoke method can be used to pass a class that can act as a closure or a continuation, or simply as a function that you can pass around.

    A lot of functional programming relies on first class functions. Even normal imperative programming can benefit from this.

    Say you had a sort routine, but wanted to support different compare functions. Well, you can have different compare classes that implement the __invoke function and pass in instances to the class to your sort function, and it doesn't even have to know the name of the function.

    Really, you could always have done something like passing a class and have a function call a method, but now you can almost talk about passing a "function" instead of passing a class, although it's not as clean as in other languages.