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

php-从匿名回调访问外部类,php,class,callback,anonymous-function,Php,Class,Callback,Anonymous Function,我有这样一个代码: class Server { private $stopper; public function setStopper() { $this->stopper = TRUE; } public function startServer() { $consumer = new Consumer(); $consumer->onConsume(function($data) { global $consumer;

我有这样一个代码:

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()
。到目前为止,我已经设置了时间限制,以便在一段时间后停止代码。但是我需要实现
setStopper
方式,这样我就可以在需要时停止服务器,而不是“过一会儿”

我之所以需要它,是因为
onConsume
连接到一个流式API,并在有新数据可用时运行匿名回调,我不想因为一些锁问题在超时时杀死php应用程序。我想优雅地停止服务器

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

...(function($data) use ($this) {...
我还想过将类值存储在回调中,但是动态调用
setStopper
,并且可能不会更新值

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

跟进:

您可以围绕
$consumer
对象以及词法对象
$this
(如果您使用的是PHP<5.4,您需要将
$this
重命名为其他名称,因为您无法
使用($this)
):

请参见链接到手册页面上的示例#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\u start/ob\u end\u flush的输出缓冲区 我拥有的一个函数应该是动态的(但是我输入的参数应该将它们插入数组中,以便以后使用$buffer解析缓冲区) 在与ob_start at time关联的解析器中,我从一个充满数据的数组中获得以下代码行:

if(!empty($this->__b2))
        array_filter ($this->__b2,function($var)use(**&$buffer**){
                $buffer = preg_replace("/<\/body>/i", $var.'</body>', $buffer);
        });
if(!empty($this->\uuu b2))
数组过滤器($this->\\uu b2,函数($var)使用(**&$buffer**){
$buffer=preg_replace(“//i”,“$var.”,$buffer);
});
我只使用一类单例,我使用“:”很多。 你怎么看我的情况
数组\u筛选器在没有&$buffer的情况下出现故障

setStopper
中更新
stopper
是否会影响回调中的
$stopper
?在php中一切都是“通过引用”的吗?对象是的。那好吧!我会更新我的代码并验证它是否运行,谢谢,我会让你知道的嘿,介意我再问一个问题吗?如果我将其用作一个单例类,并执行另一个php脚本来获取实例并设置塞子,那么它实际上不会停止消费!我能知道为什么吗?我的意思是,如果整个过程都是通过引用进行的,并且如果我理解singleton类的工作原理,那么设置stopper应该会正确地停止服务器?但事实并非如此!即使我调用了
setStopper
if(!empty($this->__b2))
        array_filter ($this->__b2,function($var)use(**&$buffer**){
                $buffer = preg_replace("/<\/body>/i", $var.'</body>', $buffer);
        });