我目前正在搞乱PHP,我注意到一些我个人没有注意到的有趣内容。匿名函数似乎不在对象内部工作。为什么呢?
示例:
$loop = function ($do) {
$i = 2;
$do((object) [
"i" => $i,
"domore" => (function () {
echo "hi";
})
]);
};
$loop(function ($data) {
echo $data->i;
echo $data->domore();
});
引发错误:
2<br />
<b>Fatal error</b>: Uncaught Error: Call to undefined method stdClass::delay() in [...][...]:16
Stack trace:
#0 [...][...](10): {closure}(Object(stdClass))
#1 [...][...](17): {closure}(Object(Closure))
#2 {main}
thrown in <b>[...][...]</b> on line <b>16</b><br />
同样,返回数据的相同代码是数组而不是对象:
$loop = function ($do) {
$i = 2;
$do([
"i" => $i,
"domore" => function () {
echo "hi";
}
]);
};
$loop(function ($data) {
echo $data["i"];
echo $data["domore"]();
});
只需按预期返回2hi
即可。这对我来说似乎是一种奇怪的行为(来自javascript的人)所以我会感谢某种理由。请注意,此代码不具有实际用途,因此优良或不良的实践对此没有任何影响。想想教育。
编辑: Laravel完全符合我的要求,这让我觉得这不是不可能,但我只是在PHP中错误地实现了它:
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.id', '=', 'contacts.user_id')->orOn(...);
})->get();
答案 0 :(得分:3)
匿名函数在对象中工作正常。你得到了这个错误,因为domore
不是一个方法而你正在调用它,它是一个恰好是闭包的属性。为了区分您在寻址属性时需要使用括号,例如:
$loop(function ($data) {
echo $data->i;
echo ($data->domore)();
});
输出:
2hi
为什么这是必要的,因为方法和属性存在于不同的符号表中,这意味着你可以拥有一个属性和一个同名的方法(请不要这样做)你需要知道哪个正在解决。 E.g:
$foo = new class
{
public $func;
public function __construct()
{
$this->func = function () {
echo "foo";
};
}
public function func()
{
echo "bar";
}
};
($foo->func)();
$foo->func();
输出:
foobar