簡體   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