PHP 之 SplObjectStorage对象存储

1. 定义

php.net上的定义 The SplObjectStorage class provides a map from objects to data or, by ignoring data, an object set. This dual purpose can be useful in many cases involving the need to uniquely identify objects. 翻译:SplObjectStorage类提供从对象到数据映射功能,或者,通过忽视数据来提供对象集合,在很多涉及需要唯一对象的许多情况下,这两点是十分有用的。

SplObjectStorage类实现了对象存储映射表,应用于需要唯一标识多个对象的存储场景。 在PHP5.3.0之前仅能存储对象,之后可以针对每个对象添加一条对应的数据。 SplObjectStorage类的数据存储依赖于PHP的HashTable实现,与传统的使用数组和spl_object_hash函数生成数组key相比, 其直接使用HashTable的实现在性能上有较大的优势。 有一些奇怪的是,在PHP手册中,SplObjectStorage类放在数据结构目录下。 但是他的实现和观察者模式的接口放在同一个文件(ext/spl/spl_observer.c)。 实际上他们并没有直接的关系。《深入理解php内核》

2. 接口说明

class SplObjectStorage implements Countable, Iterator, Serializable, ArrayAccess {
 //省略,下边详细解释以及翻译
}

此类实现了 Countable, Iterator, Serializable, ArrayAccess 四个接口,分别对应统计,迭代,序列化和数组访问,四个接口分别说明如下

2.1 Countable

此接口中只有一方法count(),看SplObjectStorage 类中此方法的说明(源码位置在php.jar/stubs/SPL/SPL_c1.php文件的1979行,可以用phpstorm按住command鼠标左键跳转过去)

/**
 * Returns the number of objects in the storage //返回存储中的对象数量
 * @link https://php.net/manual/en/splobjectstorage.count.php
 * @return int The number of objects in the storage.
 * @since 5.1.0
 */
public function count () {}

翻译注释:Returns the number of objects in the storage //返回存储中的对象数量

2.2 Iterator

接口注释Interface for external iterators or objects that can be iterated 的翻译为外部迭代器或可以迭代的对象的接口,此接口中有5个方法分别如下(对应注释中有翻译)

/**
 * Rewind the iterator to the first storage element //将迭代器回到第一个存储的元素
 * @link https://php.net/manual/en/splobjectstorage.rewind.php
 * @return void 
 * @since 5.1.0
 */
public function rewind () {}

/**
 * Returns if the current iterator entry is valid //返回当前迭代器条目是否有效
 * @link https://php.net/manual/en/splobjectstorage.valid.php
 * @return bool true if the iterator entry is valid, false otherwise.
 * @since 5.1.0
 */
public function valid () {}

/**
 * Returns the index at which the iterator currently is//返回当前迭代对应的索引
 * @link https://php.net/manual/en/splobjectstorage.key.php
 * @return int The index corresponding to the position of the iterator.
 * @since 5.1.0
 */
public function key () {}

/**
 * Returns the current storage entry //返回当前存储的条目
 * @link https://php.net/manual/en/splobjectstorage.current.php
 * @return object The object at the current iterator position.
 * @since 5.1.0
 */
public function current () {}

/**
 * Move to the next entry //移到下一个条目
 * @link https://php.net/manual/en/splobjectstorage.next.php
 * @return void 
 * @since 5.1.0
 */
public function next () {}
2.3 Serializable

接口注释Interface for customized serializing.的翻译为用于自定义序列化的接口,此接口中有2个方法分别如下(对应注释中有翻译)

/**
 * Serializes the storage //序列化存储
 * @link https://php.net/manual/en/splobjectstorage.serialize.php
 * @return string A string representing the storage. //返回表示存储的字符串
 * @since 5.2.2
 */
public function serialize () {}
/**
 * Unserializes a storage from its string representation //从一个字符串表示中对存储反序列化
 * @link https://php.net/manual/en/splobjectstorage.unserialize.php
 * @param string $serialized <p>
 * The serialized representation of a storage.
 * </p>
 * @return void 
 * @since 5.2.2
 */
public function unserialize ($serialized) {}
2.4 ArrayAccess

接口注释Interface to provide accessing objects as arrays.的翻译为提供像访问数组一样访问对象的接口,此接口中有4个方法分别如下(对应注释中有翻译)

/**
 * Checks whether an object exists in the storage //检查存储中是否存在找个对象
 * @link https://php.net/manual/en/splobjectstorage.offsetexists.php
 * @param object $object <p>
 * The object to look for.
 * </p>
 * @return bool true if the object exists in the storage,
 * and false otherwise.
 * @since 5.3.0
 */
public function offsetExists ($object) {}

/**
 * Associates data to an object in the storage //给存储中的对象赋值
 * @link https://php.net/manual/en/splobjectstorage.offsetset.php
 * @param object $object <p>
 * The object to associate data with.
 * </p>
 * @param mixed $data [optional] <p>
 * The data to associate with the object.
 * </p>
 * @return void 
 * @since 5.3.0
 */
public function offsetSet ($object, $data = null) {}

/**
 * Removes an object from the storage //从存储中删除一个对象
 * @link https://php.net/manual/en/splobjectstorage.offsetunset.php
 * @param object $object <p>
 * The object to remove.
 * </p>
 * @return void 
 * @since 5.3.0
 */
public function offsetUnset ($object) {}

/**
 * Returns the data associated with an <type>object</type> //从存储中获得一个对象
 * @link https://php.net/manual/en/splobjectstorage.offsetget.php
 * @param object $object <p>
 * The object to look for.
 * </p>
 * @return mixed The data previously associated with the object in the storage.
 * @since 5.3.0
 */
public function offsetGet ($object) {}

此接口的功能用代码简单说明如下

$collection = new Supor\Collection();//假设有一Collection类,并且已经实现了ArrayAccess 接口
$collection['a'] = 10;//我们可以像给数组赋值一样给此对象赋值
var_dump($collection['a']);//也可以使用取数组值的方法取得对象的属性 而不用 '->'
//输出 int(10)

3. 方法说明

在每个方法的注释中有对应翻译,来说明这个方法的作用

/**
 * Adds an object in the storage //向存储中添加一个对象
 * @link https://php.net/manual/en/splobjectstorage.attach.php
 * @param object $object <p>
 * The object to add.
 * </p>
 * @param mixed $data [optional] <p>
 * The data to associate with the object.
 * </p>
 * @return void 
 * @since 5.1.0
 */
public function attach ($object, $data = null) {}

/**
 * Removes an object from the storage //从存储中删除一个对象
 * @link https://php.net/manual/en/splobjectstorage.detach.php
 * @param object $object <p>
 * The object to remove.
 * </p>
 * @return void 
 * @since 5.1.0
 */
public function detach ($object) {}

/**
 * Checks if the storage contains a specific object //检查存储中是否包含特定的对象
 * @link https://php.net/manual/en/splobjectstorage.contains.php
 * @param object $object <p>
 * The object to look for.
 * </p>
 * @return bool true if the object is in the storage, false otherwise.
 * @since 5.1.0
 */
public function contains ($object) {}

/**
 * Adds all objects from another storage //添加一个存储中所有对象
 * @link https://php.net/manual/en/splobjectstorage.addall.php
 * @param SplObjectStorage $storage <p>
 * The storage you want to import.
 * </p>
 * @return void 
 * @since 5.3.0
 */
public function addAll ($storage) {}

/**
 * Removes objects contained in another storage from the current storage //从当前存储中删除另一个存储中包含的对象
 * @link https://php.net/manual/en/splobjectstorage.removeall.php
 * @param SplObjectStorage $storage <p>
 * The storage containing the elements to remove.
 * </p>
 * @return void 
 * @since 5.3.0
 */
public function removeAll ($storage) {}

/**
 *从当前存储中删除另一个存储中不包含的对象
 * Removes all objects except for those contained in another storage from the current storage 
 * @link https://php.net/manual/en/splobjectstorage.removeallexcept.php
 * @param SplObjectStorage $storage <p>
 * The storage containing the elements to retain in the current storage.
 * </p>
 * @return void
 * @since 5.3.6
 */
public function removeAllExcept ($storage) {}

/**
 * Returns the data associated with the current iterator entry //返回当前迭代器条目相关的数据
 * @link https://php.net/manual/en/splobjectstorage.getinfo.php
 * @return mixed The data associated with the current iterator position.
 * @since 5.3.0
 */
public function getInfo () {}

/**
 * Sets the data associated with the current iterator entry//设置当前迭代器条目相关的数据
 * @link https://php.net/manual/en/splobjectstorage.setinfo.php
 * @param mixed $data <p>
 * The data to associate with the current iterator entry.
 * </p>
 * @return void 
 * @since 5.3.0
 */
public function setInfo ($data) {}
/**
 * Calculate a unique identifier for the contained objects //给包含的对象计算一个唯一ID
 * @link https://php.net/manual/en/splobjectstorage.gethash.php
 * @param $object  <p>
 * object whose identifier is to be calculated.
 * @return string A string with the calculated identifier.
 * @since 5.4.0
*/
public function getHash($object) {}
        

4. 使用

SplObjectStorage的对象操作

//假设有三个Collection对象
$collection1 = new Supor\Collection(['a' => 'aa', 'b' => 'bb']);
$collection2 = new Supor\Collection(['c' => 'cc', 'd' => 'dd']);
$collection3 = new Supor\Collection(['e' => 'ee', 'f' => 'ff']);

$splStorage = new SplObjectStorage();
$splStorage->attach($collection1);
//传入相同的对象会被替代
$splStorage->attach($collection1);
$splStorage->attach($collection2);
$splStorage->attach($collection3);

//统计$splStorage中有多少个对象
$count = $splStorage->count();
var_dump($count);
//得到某一对象的哈希值
$hash1 = $splStorage->getHash($collection1);
var_dump($hash1);

//检查存储中是否包含$collection3
$contains3 = $splStorage->contains($collection3);
var_dump($contains3);

//将指针后移
$splStorage->next();
//读取移动后的key
$key = $splStorage->key();
var_dump($key);

//删除某个对象
$splStorage->detach($collection3);
//统计删除后的数量
$count = $splStorage->count();
var_dump($count);

//遍历$splStorage所有对象
//遍历前先重置一下指针
$splStorage->rewind();
//当当前迭代器条目返回真时
while ($splStorage->valid()) {
    //打印当前条目
    var_dump($splStorage->current());
    //指针后移
    $splStorage->next();
}

代码执行结果如下:
执行结果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PHP Websocket 是一种在浏览器和服务器之间建立持久性连接的技术。它允许服务器主动向客户端推送数据,而不需要客户端每次发送请求。这种技术在实时通信、多人在线游戏和在线聊天等应用场景中非常常见。 在 PHP 中,可以使用 Ratchet、ReactPHP 和 Swoole 等框架来实现 Websocket 服务器。这些框架都提供了简单易用的 API,可以快速地创建一个 Websocket 服务器,并处理客户端和服务器之间的数据交换。 下面是一个使用 Ratchet 实现的 PHP Websocket 服务器的示例: ```php use Ratchet\MessageComponentInterface; use Ratchet\ConnectionInterface; use Ratchet\WebSocket\MessageComponentInterface; use Ratchet\WebSocket\WsServer; require __DIR__ . '/vendor/autoload.php'; class MyWebSocketServer implements MessageComponentInterface { protected $clients; public function __construct() { $this->clients = new \SplObjectStorage; } public function onOpen(ConnectionInterface $conn) { $this->clients->attach($conn); echo "New connection! ({$conn->resourceId})\n"; } public function onClose(ConnectionInterface $conn) { $this->clients->detach($conn); echo "Connection {$conn->resourceId} has disconnected\n"; } public function onMessage(ConnectionInterface $from, $msg) { foreach ($this->clients as $client) { if ($client !== $from) { $client->send($msg); } } } public function onError(ConnectionInterface $conn, \Exception $e) { echo "An error has occurred: {$e->getMessage()}\n"; $conn->close(); } } $server = IoServer::factory( new HttpServer( new WsServer( new MyWebSocketServer() ) ), 8080 ); $server->run(); ``` 在这个示例中,我们使用 Ratchet 框架创建了一个 MyWebSocketServer 类,实现了 MessageComponentInterface 接口。在 onOpen 方法中,我们将新连接加入到 clients 集合中,并输出一条日志。在 onClose 方法中,我们从 clients 集合中移除连接,并输出一条日志。在 onMessage 方法中,我们遍历 clients 集合,并将消息发送给所有连接,除了发送者。在 onError 方法中,我们输出错误日志并关闭连接。 最后,我们使用 IoServer 类创建一个 Websocket 服务器,并指定监听的端口为 8080。运行服务器后,我们就可以使用浏览器或其他 Websocket 客户端连接到服务器,进行实时通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值