php - 从匿名回调访问外部类 [英] php - Access outer class from an anonymous callback

查看:21
本文介绍了php - 从匿名回调访问外部类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的代码:

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 方式,这样我就可以在需要时停止服务器,而不是一段时间后".

This code is in a file that should run forever unless the setStopper() is called. So far I have set_time_limit to stop the code after a while. But I need to implement setStopper way so I can stop the server whenever needed, not "after a while".

我需要这个,因为 onConsume 已连接到流 API 并在新数据可用时运行匿名回调,并且我不想因某些锁定而在超时时终止 php 应用程序问题.我想优雅地停止服务器.

I need this because, the onConsume is connected to a streaming API and runs the anonymous call back whenever new data is available and I don't want kill the php app on timeout due to some lock issues. I want to gracefully stop the server.

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

Can anyone please tell how to access the stopper or stopServer inside the callback? Can I use following syntax?

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

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

I also thought of storing the class value inside callback, but the setStopper is called dynamically and the value might not be updated!

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

Is there a better way to handle this situation?

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

推荐答案

您可以创建一个$consumer 对象以及词法对象 $this 周围的闭包(如果您使用的是 PHP <5.4,则需要重命名 $this 到别的东西,因为你不能use($this)):

You can create a Closure around the $consumer object as well as the lexical object $this (if you're using PHP < 5.4, you need to rename $this to something else, because you cannot 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.

See Example #3 on the linked to manual page.

为了完整起见,我还应该在这里注意,如果这是一个长期存在的过程,那么在闭包内引用的对象将在函数退出后长时间挂起.例如:

I should also note here for completeness that if this is a long-lived process, then the objects being referenced inside the closure will hang around long after the function exits. For instance:

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 的额外引用将一直存在,直到类实例本身摧毁了.

This is a classic example of a closure. Normally, once the makeAdder function returns its inner variable $x will fall out of scope and be ready for garbage collection. Since it is however bound inside the anonymous function's scope, it will hang around indefinitely (until the script's termination) or the reference to the containing scope is also released (i.e. via unset($adder)). This means that once your function is called, extra references to $consumer, $this and $stopper will hang around until the class instance itself is destroyed.

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

Not being aware of this can lead to some serious performance issues.

这篇关于php - 从匿名回调访问外部类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆