__invoke() magic method might seem similar like __construct() magic method but there's a vital difference here. Which we'll look into using few examples.
What __invoke()
magic method basically does is it makes a class callable.
First Example
class DevClass
{
public function __invoke(){
var_dump('invoked');
}
}
$dev = new DevClass();
var_dump(is_callable($dev));
Here, we’ve a simple DevClass
with __invoke()
magic method. Notice that upon initializing the class, it does nothing as it does in case of __construct() magic method
. If we call is_callable()
on DevClass
object we’ll get true. But in case we comment out the __invoke()
magic method, we get false. In short __invoke()
magic magic makes a class callable.
Now you must be thinking, why’d we want to make a class callable & what’s the purpose of doing it. We’ll look this in the next example.
Second Example (Class as a function)
class HomeController
{
public function index(){
var_dump("hello from devpeel");
}
}
$controller = new HomeController();
$controller->index();
This is a usual example of some index
method inside of a class and the simple way of calling it. But we’ve scenarios where we’re registering our Controllers or classes, we don’t always want to give method name & what we can rather do is actually use the __invoke()
magic method & our class will anonymously run exactly the same but acts as a method instead & the _invoke()
magic method will handle the rendering. This kind of approach you shall see in frameworks like Laravel as well. See the code below for reference.
class HomeController
{
public function __invoke(){
var_dump("hello from devpeel");
}
}
$controller = new HomeController();
$controller();
Another Example
Now look at another practical example where __invoke()
magic method can be used to tidy things up a little. Below is the simple class AddNumbers
which adds two numbers,
class AddNumbers
{
protected $to;
protected $value;
public function __construct($to, $value)
{
$this->to = $to;
$this->value = $value;
}
public function result(){
return $this->to + $this->value;
}
}
$add = new AddNumbers(10,10);
var_dump($add->result());
Now let’s clean this up a bit. We’ll add the __invoke()
magic method here to tidy things up and improve our API for the class.
class AddNumbers
{
protected $to;
protected $value;
public function __construct($to, $value)
{
$this->to = $to;
$this->value = $value;
}
public function __invoke(){
return $this->result();
}
public function result(){
return $this->to + $this->value;
}
}
$add = new AddNumbers(10,10);
var_dump($add());
Now as you can see, we can now call the class as method, moreover we can move the result()
method functionality to __invoke()
magic method to further clean up the code as well.
Another Example (Passing values)
If you’re wondering as if we can pass values inside of __invoke()
magic method, yes we can. Let’s have a look.
class DevClass
{
public function __invoke($value){
var_dump($value);
}
}
$class = new DevClass();
$class('PHP is Awesome');