iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 27
0
自我挑戰組

花式PHP系列 第 28

PHP SPL:SplObjectStorage

它可以做什麼

SplObjectStorage 有兩種用法:

  1. 當成一個可以用物件當 key 的關聯陣列
  2. 當成一個裝滿物件的一般陣列

其中的第二種用法:
因為兩個一模一樣的物件在 SplObjectStorage 中也是等價的,
所以它可以用來檢查兩個物件是否等價,或者物件是否重複了

怎麼用

底下會示範如何對 SplObjectStorage:

  1. 新增
  2. 移除
  3. 檢查包不包含指定物件
  4. 取得集合長度
  5. 取得物件的 hash
  6. foreach、while 兩種迭代
  7. 序列化、反序列化
<?php

/**
 * 印變數用
 */
function dump(...$things)
{
    foreach ($things as $thing) {
        if ($thing instanceof SplObjectStorage) {
            foreach ($thing as $pointer => $objectKey) {
                dump($objectKey);
            }
        } else {
            echo var_export($thing, TRUE) . PHP_EOL;
        }
    }
}

/**
 * 產生物件用
 */
function generateObject($value)
{
    $object = new stdClass();
    $object->foo = $value;
    return $object;
}

$o1 = generateObject(1);
$o2 = generateObject(2);
$o3 = generateObject(3);


$set = new SplObjectStorage();

// 新增一筆資料
$set->attach($o1);

// 新增一筆資料,並為其指定 value
$set->attach($o2, 'HashMap Value - o2');

// 第二種新增資料的寫法
$set[$o3] = 'HashMap Value - o3';

// 檢查 ObjectStorage 是否存在這個物件
dump($set->contains($o1)); // TRUE
dump($set->contains($o3)); // FALSE

// 以物件當作 ObjectStorage 的 key 取得對應的資料
try {
    dump($set[$o1]); // NULL
    dump($set[$o2]); // 'HashMap Value - o2'
    dump($set[$o3]); // 'HashMap Value - o3'
    dump($set[generateObject(4)]); // UnexpectedValueException
} catch (UnexpectedValueException $e) {
    dump($e->getMessage()); // 'Object not found'
}

// 移除物件的兩種寫法
$set->detach($o1);
// 等同於 unset($set[$o1]);
$set->attach($o1);

// 取得作為 key 的物件的雜湊值
dump($set->getHash($o2)); // '000000005fb6561e000000005d9f1cda'

// 獲得 ObjectStorage 的長度
dump($set->count()); // 3
dump(count($set));   // 3

// foreach 迭代
foreach ($set as $pointer => $objectKey) {
    dump($pointer, $objectKey);
}

// while 迭代
$set->rewind(); // 重置 ObjectStorage 內部指針的位置

while ($set->valid()) { // 檢查目前指針位置
    dump(
        $set->key(), // 印出目前指針的位置,會是 int
        $set->current(), // 印出目前指針位置的 key,會是一個物件
        $set->getInfo() // 印出目前指針位置的 value
    );
    
    // 移動內部指針
    $set->next();
};

// ObjectStorage 可以序列化、反序列化
$serialized = $set->serialize();
$set = new SplObjectStorage();
$set->unserialize($serialized);
dump($set);

// 新增所有來自另一個 ObjectStorage 的物件
$newSet = new SplObjectStorage();
$newSet->addAll($set);
dump($newSet);

// 除了 $set 中的物件之外,移除 $newSet 中所有的物件
$set->detach($o2);
$newSet->removeAllExcept($set);
dump($newSet);

// 移除來自另一個 ObjectStorage 的所有物件
$newSet->removeAll($set);
dump($newSet);

上一篇
PHP SPL:SplFixedArray
下一篇
PHP SPL:RecursiveIteratorIterator
系列文
花式PHP31

尚未有邦友留言

立即登入留言