gpt4 book ai didi

php - 通过附加信息在 SplObjectStorage 中查找对象

转载 作者:可可西里 更新时间:2023-10-31 22:53:52 27 4
gpt4 key购买 nike

我使用 PHP Ratchet 构建了一个聊天应用。

我将所有连接存储在 SplObjectStorage 中。

每个连接都有用户 ID,我将通过此附加他:

   public function __construct() {
$this->clients = new \SplObjectStorage;
}

public function onOpen(ConnectionInterface $conn)
{
// Store the new connection to send messages to later
$querystring = $conn->WebSocket->request->getQuery();

foreach ($querystring as $value)
{
if($key == "senderId")
$senderId = $value;
}

$this->clients->attach($conn, $senderId);

echo "New connection! ({$conn->resourceId}) senderId({$senderId})\n";
}

当消息到达时,我希望以最快的方式获取与特定用户 ID 相关的 $conn 对象。我可以像这样使用简单的 foreach:

public function onMessage(ConnectionInterface $from, $msg) {
$numRecv = count($this->clients) - 1;
echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
, $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');

foreach ($this->clients as $client)
{
if ($from->getInfo() !== $client->getInfo()) {

// do stuff
}
}

不知道有没有更快的方法。也许使用这样的功能:

$conn = $this->clients->getClientWithInfo("WANTED-INFO");

想要的方法是取消所有连接上的循环,以便向特定用户发送消息。我想获取与用户 ID 关联的连接。

最佳答案

在我看来,只有一种解决方案可以让它发挥作用,就像您预期的那样 => 扩展 SplObjectStorage 类。但是你有两个选择。

首先,您可以偷懒并向为您找到对象的类添加一个 getClientWithInfo 方法:

class ConnectionStorageSimple extends SplObjectStorage
{
public function getClientWithInfo($info)
{
$this->rewind();
while ($this->valid()) {
$object = $this->current(); // similar to current($s)
$data = $this->getInfo();
if ($info === $data) {
$this->rewind();

return $object;
}
$this->next();
}

return null;
}
}

$conStorage = new ConnectionStorageSimple();

$con1 = new \stdClass();
$con1->id = 1;
$con2 = new \stdClass();
$con2->id = 2;


$conStorage->attach($con1, 1);
$conStorage->attach($con2, 2);

var_dump($conStorage->getClientWithInfo(1));

var_dump($conStorage->getClientWithInfo(2));

/**
This will output something like that:
class stdClass#2 (1) {
public $id =>
int(1)
}
class stdClass#3 (1) {
public $id =>
int(2)
}
*/

另一种选择是,您基于父函数构建一个信息对象映射。这有点复杂:

<?php

class ConnectionStorage extends SplObjectStorage
{

private $objInfoMapping = array();

public function attach($object, $data = null)
{
if (null !== $data) {
$this->objInfoMapping[$data] = $object;
}
parent::attach($object, $data);
}

public function detach($object)
{
$this->detach($object);
parent::detach($object);
}

public function addAll($storage)
{
$this->addStorage($storage);

parent::addAll($storage);
}

public function removeAll($storage)
{
$this->objInfoMapping = array();
parent::removeAll($storage);
}

public function removeAllExcept($storage)
{
$this->objInfoMapping = array();
$this->addStorage($storage);
parent::removeAllExcept($storage);
}

public function unserialize($serialized)
{
parent::unserialize($serialized);
$this->addStorage($this);
}

public function offsetUnset($object)
{
$this->detach($object);
parent::offsetUnset($object);
}

protected function detachObject($obj)
{
$info = $this[$obj];
if (array_key_exists($info, $this->objInfoMapping)) {
unset($this->objInfoMapping[$info]);
}
}

protected function addStorage(SplObjectStorage $storage)
{
$storage->rewind();
while ($storage->valid()) {
$object = $storage->current(); // similar to current($s)
$data = $storage->getInfo();
$this->objInfoMapping[$data] = $object;
$storage->next();
}
}

public function getClientWithInfo($info)
{
if (array_key_exists($info, $this->objInfoMapping)) {
return $this->objInfoMapping[$info];
}
}

}

$conStorage = new ConnectionStorage();

$con1 = new \stdClass();
$con1->id = 1;
$con2 = new \stdClass();
$con2->id = 2;


$conStorage->attach($con1, 1);
$conStorage->attach($con2, 2);

var_dump($conStorage->getClientWithInfo(1));

var_dump($conStorage->getClientWithInfo(2));

/**
This will also output something like that:
class stdClass#2 (1) {
public $id =>
int(1)
}
class stdClass#3 (1) {
public $id =>
int(2)
}
*/

这两个类之间的主要区别在于,第二个示例在大数据集上表现更好,因为您不必遍历存储的所有对象。而且因为您只存储对自己数组的对象引用,所以额外的内存消耗应该不会太大。

免责声明:这些类(class)只是为了说明可能性。第一个留着用,第二个要多测试

希望这对您有所帮助。

关于php - 通过附加信息在 SplObjectStorage 中查找对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28792051/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com