在php5.3版本及之后,当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用
下面是一个调用的实例,来深刻理解一下他的运行机制。
<?php
/**
* 当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。
*/
class basicA
{
protected $varA;
protected $varB;
function __construct($var)
{
$this->varA = $var;
echo "arrive in ".__METHOD__.",this->varA:{$this->varA}<br/>";
}
function modifyVar($var)
{
echo "arrive in ".__METHOD__."<br/>";
$this->varA = $var.'111';
$this->varB = $var.'222';
}
}
class currA extends basicA
{
function __invoke($var)
{
echo "arrive in ".__METHOD__."<br/>";
if (!empty($this->varA) && $this->varA == 'are you ok?') {
$this->modifyVar($var);
}
}
}
class currB
{
function __invoke($var)
{
echo "arrive in ".__METHOD__."<br/>";
var_dump($var);
echo '<br/>';
}
}
$objA = new currA('are you ok?'); //直接定义对象,会进入到基类构造函数中,但不会进入到__invoke方法中
var_dump($objA);
echo '<hr/>';
$objA = new currA('are you ok?');
$objA('are you ok?'); //这样调用会进入到__invoke方法中,也会进入到基类modifyVar()方法中
//即使有两个初始化语句,可以看到基类的构造方法也只会进入一次
var_dump($objA);
echo '<hr/>';
$objB = new currB('how are you?');
$objB('how are you?');
var_dump($objB);
echo '<br/>';
var_dump(is_callable($objB));
echo '<br/>';
echo '<hr/>';
运行之后的结果如下:
lumen中如果Controller中没有定义构造方法,但是父类有构造方法,如果该控制器有__invoke方法,会相当于调用以下语句的效果
$objA = new currA('are you ok?');
$objA('are you ok?');