php代码如下:
class bird{
public function __construct($str){
echo "bird __con
".$str;
}
}
$eagle=new bird('fly');
//给类的属性/方法赋值一个 匿名函数之后
$eagle->onWorkerStart = function($str){
var_dump($str);
$chicken=new bird('egg');
$chicken->onMessage = function($buffer){
out_f($buffer); //执行外部定义的方法会不会报错?
};
};
$eagle->onWorkerStart(); //这样会报错
($eagle->onWorkerStart)(); //这样也会报错
function out_f($buffer){
echo "out_f".$buffer;
}
问题一:$eagle->onWorkerStart 如何执行???
问题二:$chicken->onMessage里面执行外部定义的方法out_f($buffer)会不会报错?
回答
问题一
用这种方式构建的匿名 onWorkerStart 实际上会成为一个 Closure 对象, 因此你需要调用 Closure 对象的 call 方法 (此处 PHP 应该是参考了 Javascript)
$eagle->onWorkerStart->call($eagle, 'hello'); // 'hello' 为 onWorkerStart 函数的参数
不过个人并不建议你这么做, 对代码可读性伤害很大. 哪怕在 Bird 类里面分别 public 声明下 onWorkerStart 和 onMessage 也会好很多. 并进一步可以用 phpdoc 标示一下它们的类型为 Closure, 现代IDE 可以识别这个语法并根据对应类型提供语法提示.
class bird{
/**
* @var \Closure
*/
public onWorkerStart;
/**
* @var \Closure
*/
public onMessage;
/*.....*/
}
当然 PHP 7.4 以上可以直接声明类型:
class bird{
public \Closure onWorkerStart;
public \Closure onMessage;
/*.....*/
}
问题二:
不会, 函数是全局作用域的