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

查看:245
本文介绍了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.

任何人都可以告诉如何访问 stopServer 里面的回调?我可以使用以下语法吗?

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 - 动态更新Singleton类的值

推荐答案

您可以创建 $ 对象以及词法对象 $ this 're use 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天全站免登陆