somemo's diary

プログラマ、雑記、プログラミング関係はLinkから、数式はこっちでまとめていることが多い

【php】オブジェクトをキーにデータと関連付ける

タイトルどおりです。JavaのHashMapのようにオブジェクトをキーにすることができるデータ構造がphpにもありましたので、試しました。

SplObjectStorageクラス

このクラスがphpで実現するためのものです。5.3以降でないと使えないですが、とても便利です。

テストコードを書いてみました。また、Pairクラスを使っています。

/**
 * SplObjectStorageのテスト
 */
public function testStorageEquals() {
    $storage = new SplObjectStorage();
    $pair = new Pair('USD', 'CHF');
    $storage->offsetSet($pair, 1);

    $this->assertTrue($storage->offsetExists($pair));
    $this->assertFalse($storage->offsetExists(new Pair('USD', 'CHF')));

    $this->assertEquals(1, $storage->offsetGet($pair));
}

内容は以下のとおりです。

  1. SplObjectStorageの生成
  2. Pairの生成(引数をメンバ変数に格納するだけ)
  3. SplObjectStorageに生成したPairをキーに、1を関連付けて格納
  4. SplObjectStorageに生成したPairが含まれるかテスト(含まれている)
  5. SplObjectStorageに生成したPairと同じ内容のオブジェクトが含まれるかテスト(含まれていない)
  6. SplObjectStorageに生成したPairに関連付けたデータのテスト(きちんと1が返ってくる)

このように、オブジェクトをキーにデータの格納および関連付けができています。

ただし、5番からもわかるようにオブジェクトも一致しないとだめです。このため、生成したPairを保持していないといけませんので、動的にデータを取得したり、含まれているかの確認が行えません。

phpでは、オブジェクトの等価性やハッシュコードをクラスごとに設定するマジックメソッドがないので仕方ありません。

オブジェクトの比較でも述べたように、比較を緩くするか厳密にするかの選択を自由に行えるので、自由に選択させてもらいたいところです。

導入に書いてある一意という点に反しているからなのかな?

SplObjectStorage クラスは、オブジェクトをデータに対応させたり、 データを渡さずオブジェクトセットとして使用したりします。 これらはどちらも、オブジェクトを一意に特定したい場合に便利です。

参考