6

私は現在resource、ルックアップのために s をハッシュする次の方法を使用しています。

$foo = socket_create(...);
$bar = socket_create(...);

$map[(int)$foo] = 'foo';
$map[(int)$bar] = 'bar';

echo $map[(int)$foo]; // "foo"

これにはintegerキャストが最適なオプションですか?そうでない場合、他のどのハッシュ方法がより優れた、またはより効率的でしょうか? これらのルックアップは、タイト ループ (ソケット ポーリング) で 1 秒間に何度も数百回のコレクションで実行されるため、反復ベースのソリューションは既に除外しています。

編集:

私の状況をもう少し詳しく説明すると、socket_select()関数は参照によってソケット リソースの配列を取得し、関数呼び出し後に変更されたリソースのみが含まれるように変更します (たとえば、読み取りの準備ができています)。Socketコードをより抽象的でテストしやすくするために、クラスをソケット リソースのラッパーとして使用します。

$socketObject = new Socket($socketResource);

私の別のクラスでは、 を呼び出すたびにポーリングする必要があるすべてのソケット リソースのリストを保持していますsocket_select()

$reads = [$socketResource1, $socketResource2, ...];
socket_select($reads, null, null, 0);

を呼び出した後、socket_select()どのソケットリソースが変更されたかがわかりますが、コードで意味のあることを行うには、それらのリソースがどのソケットオブジェクトに対応しているかを知る必要があります。したがって、ソケット リソースをオブジェクトにマップする方法が必要です。

foreach ($reads as $socketResource) {
    // Which socket object does $socketResource correspond to here?
    // Currently, I use a solution like this:
    $socketObject = $this->map[(int)$socketResource];
    // Unfortunately, this behavior isn't guaranteed, so it isn't reliable...
}
4

4 に答える 4

0

$map変数の代わりにコレクション オブジェクトを作成することをお勧めします。

class ResourceCollection implements ArrayAccess {

  private $map = array();

  /**
   * returns index of element or FALSE if not existent
   */
  protected function getIndex($offset){
    if(is_resource($offset)){
      $index = array_search($offset, $this->map);
    }
    else // you can add more tests if you need
      if(isset($this->map[$offset]))
        $index = $offset;
      else
        $index = false;
    return $index;
  }

  /**
   * required by ArrayAccess interface
   */
  public function offsetExists($offset){
    return ($this->getIndex($offset) === false)? false : true;
  }



  /**
   * required by ArrayAccess interface
   */
  public function offsetGet($offset){
    $index = $this->getIndex($offset);
    if($index === false)
      throw new ... // or handle error of non-existent element
    return $this->map[$index];
  }

// etc., implement ArrayAccess interface, Iterator and anything you want
}

私はそれをテストしていませんが、これにより、あたかも配列であるかのようにオブジェクトにアクセスできるはずであり、この方法 (これに関するドキュメントはありません) のリソースを配列インデックスとして使用できることを願っています。

于 2013-07-31T08:56:12.397 に答える