繁体   English   中英

php-从匿名回调访问外部类

[英]php - Access outer class from an anonymous callback

我有这样的代码:

class Server {
  private $stopper;

  public function setStopper() { $this->stopper = TRUE; }

  public function startServer() {
    $consumer = new Consumer();
    $consumer->onConsume(function($data) {
      global $consumer;
      // some processing
      if( ?? ) { // how to access stopper here??
         $consumer->stop();
         // also how to access stopServer() here??
      }
    });
    $consumer->consume();
  }

  public function stopServer() { ... }

}

除非调用setStopper()否则此代码位于应永久运行的文件中。 到目前为止,我已经使用set_time_limit在一段时间后停止了代码。 但是我需要实现setStopper方式,以便可以在需要时停止服务器,而不是“过一会儿”。

我需onConsume ,因为onConsume连接到流API并在有新数据可用时运行匿名回调,并且由于某些锁定问题,我不想在超时时onConsume php应用。 我想优雅地停止服务器。

谁能告诉我如何在回调中访问stopperstopServer 我可以使用以下语法吗?

...(function($data) use ($this) {...

我还考虑过将类值存储在回调中,但是setStopper是动态调用的,该值可能不会更新!

有没有更好的方法来处理这种情况?

跟进: php-动态更新Singleton类的值

您可以在$consumer对象以及词法对象$this周围创建一个Closure (如果您使用的是PHP <5.4,则需要将$this重命名$this其他名称,因为您不能use($this) ):

 $self = $this;
 // You may not need to do this, I cannot remember off-hand whether 
 // closures have access to private variables or not
 $stopper = $this->stopper;
 $consumer->onConsume(function($data) use($consumer, $self, $stopper) {
  if( $stopper ) {
     $consumer->stop();
     $self->stopServer();
  }
});

请参阅链接到手册页上的示例3。

为了完整性,我还应该在这里指出,如果这是一个长期的过程,那么在函数退出后,闭包内部被引用的对象将挂掉很长时间。 例如:

function makeAdder($x) {
    return function($n) use($x) {
        return $x + $n;
    };
}

$adder = makeAdder(5);
echo $adder(2); // Output 7
echo $adder(5); // Output 10
echo $adder(4); // Output 9

这是关闭的经典示例。 通常,一旦makeAdder函数返回其内部变量$x它将超出范围并准备进行垃圾回收。 但是,由于它绑定在匿名函数的作用域内,因此它将无限期地挂起(直到脚本终止), 或者也释放了对包含作用域的引用(即,通过unset($adder) )。 这意味着一旦调用了函数,对$consumer$this$stopper额外引用将一直存在,直到类实例本身被销毁为止。

不了解这一点可能会导致一些严重的性能问题。

相同的问题在这里,我使用ob_start / ob_end_flush的输出缓冲区,而我拥有的一个函数应该是动态的(但是我推入的参数应该将它们插入数组中,以便以后使用$ buffer解析缓冲区)在与ob_start关联的解析器中当我从一个充满数据的数组中获得这些代码行时:

if(!empty($this->__b2))
        array_filter ($this->__b2,function($var)use(**&$buffer**){
                $buffer = preg_replace("/<\/body>/i", $var.'</body>', $buffer);
        });

我只使用一个类的单例,并且经常使用“ ::”。 在我的情况下,您如何看待没有&$ buffer的array_filter出现故障

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM