我试图使用闭包编写类似js的php。但是,我不明白为什么不能将闭包分配给stdClass属性。
代码说明了自己
$sum = function ($a, $b) {return $a + $b;};
echo $sum(11, 11);
// prints 22
$arr = [];
$arr['sum'] = function ($a, $b) {return $a + $b;};
echo $arr['sum'](22, 22);
// prints 44
$cl = new stdClass;
$cl->sum = function ($a, $b) {return $a + $b;};
echo $cl->sum(33, 33);
// Fatal error: Uncaught Error: Call to undefined method stdClass::sum()
# although I can't think of any use cases for this
class Custom {
public $sum = NULL;
function __construc() {
$this->sum = function ($a, $b) {return $a + $b;};
}
}
$custom = new Custom;
echo $custom->sum(44, 44);
// Fatal error: Uncaught Error: Call to undefined method Custom::sum()
答案 0 :(得分:0)
只需将属性名称括在方括号中即可。
echo ($cl->sum)(33, 33);
echo ($custom->sum)(44, 44);
3v4l中的示例:
根据评论进行编辑:
Javascript中的对象只能具有属性。该属性可以是原始值,其他对象或函数,但是该属性的名称尽管具有内容,但还是唯一的。
在PHP中,对象可以同时具有属性和方法。
假设我们有以下代码:
class MyClass
{
public $foo;
public function __construct()
{
$this->foo = function(int $a, int $b): int {
return $a * $b;
};
}
public function foo(int $a, int $b): int
{
return $a + $b;
}
}
$myClass = new MyClass();
echo $myClass->foo(2, 3);
属性foo
和方法foo
都具有相同的签名,但是程序员的意愿是什么?
此代码将调用方法foo
并显示5,因此任何行$var->name()
都被解释为方法调用。
如果要在属性内部调用闭包,则必须使用其他语法,以免产生歧义。
echo ($myClass->foo)(2, 3) //Prints 6
答案 1 :(得分:0)
您可以使用闭包方法bind()
,bindTo()
或call()
。
$cl = new stdClass;
$sum = function ($a, $b) {return $a + $b;};
Closure::bind($sum, $cl);
echo $sum(33, 33); // this function is now part of the class.
如果希望扩展此功能,则可以在类中创建一个注册函数,该函数依赖于__call()
之类的魔术方法来检查该方法是否存在,如果存在,请在内部调用此方法。 / p>