php-通过附加信息在SplObjectStorage中查找对象
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了php-通过附加信息在SplObjectStorage中查找对象,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4087字,纯文字阅读大概需要6分钟。
内容图文
![php-通过附加信息在SplObjectStorage中查找对象](/upload/InfoBanner/zyjiaocheng/662/30838c396a434fe58075ef6b550705d2.jpg)
我使用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)
}
*/
这两个类之间的主要区别在于,第二个示例在大型数据集上的性能更好,因为您不必遍历存储的所有对象.
并且由于您仅将对象引用存储到自己的数组,因此额外的内存消耗不会太大.
免责声明:这些类只是为了说明可能性.第一个应该保存使用,但是第二个应该进行更多测试
希望这可以帮助.
内容总结
以上是互联网集市为您收集整理的php-通过附加信息在SplObjectStorage中查找对象全部内容,希望文章能够帮你解决php-通过附加信息在SplObjectStorage中查找对象所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。