我正在处理一个线程包装器类,它可以接收一个函数并在新线程中调用该函数。到目前为止,这是我的课:
public function __construct($cbCallback, $aParameters) {
$this->cbCallback = $cbCallback;
$this->aParameters = $aParameters;
$this->return = false;
}
public function run() {
if (is_array($this->cbCallback)) {
$this->return = call_user_func($this->cbCallback, ...($this->aParameters));
}
else {
$this->return = $this->cbCallback(...($this->aParameters));
}
}
这在接收回调时使用call_user_func部分。我想重载这个类,这样它也可以接受闭包而不是回调数组。我在将匿名函数存储为类变量时遇到了麻烦:它总是存储为null。
我在构造函数中放入了一些调试语句:
echo "Paramater test 1: " . json_encode($cbCallback);
$this->cbCallback = $cbCallback;
echo "Paramater test 2: " . json_encode($cbCallback);
echo "Variable test: " . json_encode($this->cbCallback);
这就产生了输出:
Paramater test 1: {}
Paramater test 2: {}
Variable test: null
我还尝试过用&$cbCallback
通过引用传递$cbCallback
,这只会导致对象无法通过引用传递的错误。
我觉得要么是匿名函数有一个特殊的规则,要么是发生了一些不稳定的事情。为什么我不能将匿名函数存储到$this->cbCallback中?有没有任何方法可以将匿名函数存储在(非静态)类变量或类似的东西中,当我需要调用该函数时,这些方法可以以相同的方式工作?
附言:我使用的是PHP v5.6
如果您想执行存储在对象中的闭包,请尝试先将其分配给一个变量,否则可能会得到"调用未定义的方法"。
代替
$this->return = $this->cbCallback(...($this->aParameters));
试试这个
$cb = $this->cbCallback;
$this->return = $cb(...($this->aParameters));
我终于找到了我遇到的问题。事实证明,这是pthreads库的一个问题。
只要不扩展Thread
类,指定的代码就可以完美地工作。
我在php的网站上发现了这个错误报告:https://bugs.php.net/bug.php?id=67506
然后将其发布到krakjoe的github:https://github.com/krakjoe/pthreads/issues/355
事实证明,他在我发帖前几个小时就已经解决了这个问题,所以要解决这个问题,请确保您运行的是pthreadsv2.0.9+.
您可以在类变量中存储闭包或lambda函数/匿名函数。但是,您不能序列化它,因为它不仅仅是一个简单的值,而是一个函数。