いけむランド

はてダからやってきました

SplObjectStorage について考えてみた

PHP では array はキーに object をとることができない。

array や object は、キーとして使えません。 キーとして使おうとすると Illegal offset type という警告が発生します。


そのため、キーに object をとることができる標準クラスがある。

SplObjectStorage クラスは、オブジェクトをデータに対応させたり、 データを渡さずオブジェクトセットとして使用したりします。


けれども、このクラスは個人的に気持ち悪い。

それは Map としても Set としても使えるということである。

元々 Map の実装であるが、キーの object に対して、値を null で保持することで Set を実現しているらしい。

あと、Map として使う場合に foreach も気持ち悪くなる。

$map = new \SplObjectStorage();
$key1 = new stdClass();
$map[$key1] = 'value1';
$key2 = new stdClass();
$map[$key2] = 'value2';
foreach ($map as $key => $value) {
  var_dump($key, $value);
}


これを実行すると以下のような出力となる。

int(0)
class stdClass#2 (0) {
}
int(1)
class stdClass#3 (0) {
}


キーと値をきちんと舐める場合は以下のように書かないといけない。

foreach ($map as $value) {
  var_dump($value, $map[$value]);
}


ちなみに key() をオーバーライドして object を返すように定義すると、上述の通り Illegal offset type と怒られる。><

オレオレ実装で Map として気持良く使わせたい場合にはどうすればよいだろうと考えてみたら、each() メソッドをつくってあげるのが良いのではないかと思った。