Some PHP Magic with __invoke

15 04 2010

__invoke is a magic method available in PHP5.3. This is something that I nearly overlooked until I chanced to browse Matthew Weier O’Phinney’s blog last night in which he has a thought provoking tutorial on this latest feature of PHP.

O’Phinney shows that it is very easy to call an object as if it were a function with __invoke. He shows that the way it works is to have an object that has such a method and then you decide what you want the method to actually do, i.e. call another method or return a value. His first example is easy to grasp altho’ my mind is still spinning from the notion of calling an object as if it were a function. First I learn that procedural programming is passe, replaced by OOP and now we’re treating objects as if they were functions! Does this make any sense? Apparently it does as it allows for less code to be written.

His second example takes up the issue of how can one know whether an object may be invoked, i.e. how can we know that it is “callable”? He suggests that we could use is_callable() but doesn’t provide an example, so I will do so, as follows:


class Mirror
{
public function __invoke($value) {
echo $value;
}
}
$mirror = new Mirror();
$ObjMethod = array($mirror, "__invoke");
if ( is_callable($ObjMethod, true, $callable_name) ){
$mirror("Invoking object as if it were just a function -- kewl!");
}
else {
echo $mirror->__invoke("Doing it the old-fashioned way");
}

So, when the if is true then I know that $mirror is callable and I can call the object as I did above. The only wierd part is that it feels more natural to call the object with its callable name but that won’ work. I also tried using $ObjMethod by prepending parens and that didn’t work either. So, the parameters that you give to is_callable(), unlike what its name may suggest are not intended to be used to invoke the object. Only invoking the object works.

The second example also shows that you could use interfaces to determine whether an object is callable. I personally found the second example more complicated looking than I needed to grasp the point. So, I offer my simplified example as follows:


interface Invoker{
public function __invoke($value);
}
class Mirror implements Invoker
{
public function __invoke($value) {
echo $value;
}
}
$mirror = new Mirror();
if ($mirror instanceof Invoker) {
$mirror("This works, too!");
}

His last code example demonstrates that object properties that have an __invoke method one must handle with care. The code in this section is very easy to understand.

While I am intrigued with the notion of __invoke, I do wonder if it is questionable syntactic sugar. Maybe there’s too much magic going on underneath PHP these days; the magicians, i.e. the PHP language designers need to explain their tricks better or else revise them so they are more in line with the transparent and practical nature that traditionally has distinguished PHP and made it so wildly popular.

This work is licensed under a Creative Commons License
.

Advertisements

Actions

Information

One response

15 11 2012
sda

thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: