PHP 5.4超时调用闭包



我只是在模仿我正在处理的一个intercept类。想法是通过intercept类实例化该类,然后使用该对象,就好像它是你正在拦截的类一样。然后,每次调用类时都会运行指定的回调。这是代码:

<?php
class Intercept {
    protected $class = null;
    protected $callback = null;
    public function __construct($class, $callback = null) {
        $this->class = new $class();
        $this->callback = $callback;
    }
    protected function run_callback() {
        $this->callback();
    }
    public function __get($name) {
        $this->run_callback();
        return $this->class->$name;
    }
    public function __set($name, $value) {
        $this->run_callback();      
        return $this->class->$name = $value;
    }
    public function __isset($name) {
        $this->run_callback();
        return isset($this->class->$name);
    }
    public function __unset($name) {
        $this->run_callback();
        unset($this->class->$name);
    }
    public function __call($method, $args) {
        $this->run_callback();
        return call_user_func_array(array($this->class, $method), $args);
    }
    public function __toString() {
        $this->run_callback();
        return $this->class;
    }
    public function __invoke() {
        $this->run_callback();
        return $this->class();
    }
}
class test {
    public function hello() { 
        return 'world'; 
    }
}
$closure = function() {
    echo 123;
};
$test=new Intercept('test', $closure);
echo $test->hello();

现在,运行上面的代码应该显示'world123'。但由于某种我看不见的奇怪原因,它最终超时了。我在本地机器和各种php5.4测试网站上进行了测试。同样的事情也会发生。我已经将它缩小到run_callback()方法中正在运行的闭包($this->callback())。如果我只是删除$this->callback(),它工作得很好。为什么会发生这种情况?

编辑,当我写这个问题时,我发现不是:

$this->callback();

这样做将停止超时:

$closure = $this->callback;
$closure();

似乎每次我尝试直接从类属性运行闭包时,都会调用__call方法。这是预期的行为,还是我被PHP错误绊倒了?

很确定这是因为函数调用堆栈有一个无限循环。当你做

$this->callback();

您正在尝试执行成员函数callback(),但它不存在,因此执行__call(),它再次尝试callback(),但它并不存在,所以执行__call(),依此类推。

您应该使用以下内容:

call_user_func( $this->callback);

或者,就像你编辑的那样,这也会起作用:

$closure = $this->callback;
$closure();

希望这能澄清正在发生的事情。超时只是因为您的资源(在本例中是时间)用完了。根本问题是无限循环。

相关内容

  • 没有找到相关文章

最新更新