为啥 $handler 在回调中得到不同的值?
Posted
技术标签:
【中文标题】为啥 $handler 在回调中得到不同的值?【英文标题】:Why $handler is getting different value inside callback?为什么 $handler 在回调中得到不同的值? 【发布时间】:2016-02-22 17:33:36 【问题描述】:每当我在回调中打印处理程序的客户端时,即使添加了几个客户端,它也会显示为空。
我对 php 很幼稚,似乎每次我调用回调函数时都会传递处理程序的新对象。
<?php
$handler=new Handler();
$server = ioserver::factory(
new HttpServer(
new WsServer(
$handler
)
),
9090
);
$callback = function($msg)
echo " [x] Received ", $msg->body, "\n";
echo $handler->test."\n";
;
$pid=pcntl_fork();
if ( $pid == -1 )
echo "server start fork failed";
exit(1);
else if ( $pid )
$server->run();
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('hello', false, false, false, false);
$channel->basic_consume('hello', '', false, true, false, false, $callback);
while(count($channel->callbacks))
$channel->wait();
echo count($channel->callbacks);
?>
下面是处理程序文件
<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Handler implements MessageComponentInterface
public $clients;
public $test="Test";
private $handler;
public function __construct()
$this->clients = new \SplObjectStorage;
public function onOpen(ConnectionInterface $conn)
"echo added";
$this->clients->attach($conn);
public function onMessage(ConnectionInterface $from, $msg)
$this->test="onMessage";
foreach ($this->clients as $client)
if ($from !== $client)
// The sender is not the receiver, send to each client connected
$client->send($msg);
public function sendAll($msg)
$this->test="sendAll";
foreach ($this->clients as $client)
$client->send($msg);
public function onClose(ConnectionInterface $conn)
$this->clients->detach($conn);
public function onError(ConnectionInterface $conn, \Exception $e)
$conn->close();
public function getInstance()
if(empty($this->handler))
$this->handler=new Handler();
return $this->handler;
?>
【问题讨论】:
$handler
将超出您的回调范围....$callback = function($msg) use($handler) echo " [x] Received ", $msg->body, "\n"; echo $handler->test."\n"; ;
也许
我已经尝试过你的方法但没有用,我还尝试使用 $GLOBAL 来保存处理程序并在回调中使用它。看起来当我们将对象传递给 WsServer 时,它被克隆了,现在我们有 2 个处理程序副本,这就是为什么我们为“测试”变量获得相同的值,为了消除这个错误,我还尝试将引用传递给 WsServer,但仍然无法正常工作。
【参考方案1】:
使用单例。
不是这个:
// class Handler...
private $handler;
...
public function getInstance()
if(empty($this->handler))
$this->handler=new Handler();
return $this->handler;
$handler=new Handler();
但是这个:
// Changed class Handler...
private static $handler;
...
public static function getInstance()
if(empty(self::$handler))
self::$handler=new Handler();
return self::$handler;
$handler=Handler::getInstance();
[edit] Handler::getInstance() 当前不是静态的,在我写完答案后发现了这一点。
【讨论】:
以上是关于为啥 $handler 在回调中得到不同的值?的主要内容,如果未能解决你的问题,请参考以下文章
为啥用 viewLifecycleOwner 观察到的 LiveData 在 onDestroyView 之后会得到回调?
为啥 Chrome 和 Firefox 以不同方式处理 jQuery ajax() 回调中设置的 javascript 变量?