したがって、これが PHP のバグのある設計なのか、それとも同じインターフェイスで一貫性のない結果を処理するための理解されたロジックがあるのかはわかりません。
SeekableIterator インターフェイスには 2 つのメソッド (seek
およびvalid
) があり、これらは互いに競合しているか、互いに一貫して動作するはずですが、両方とも表示されます。
インターフェイスのドキュメントにはseek
、クラス OutOfBoundsException の例外をスローする必要があると記載されていますが、これは、例外をスローする前valid
にイテレーターの位置が更新されない限りvalid
(明らかに false を返すように)、の有用性を無効にしているようです (これは明らかにキャッチする必要があります)。
3 つのテスト例
例 1。
ドキュメントの例で提供されているように、SeekableIterator を実装するカスタム クラス:
クラス:
class MySeekableIterator implements SeekableIterator {
private $position;
private $array = array(
"first element",
"second element",
"third element",
"fourth element"
);
/* Method required for SeekableIterator interface */
public function seek($position) {
if (!isset($this->array[$position])) {
throw new OutOfBoundsException("invalid seek position ($position)");
}
$this->position = $position;
}
/* Methods required for Iterator interface */
public function rewind() {
$this->position = 0;
}
public function current() {
return $this->array[$this->position];
}
public function key() {
return $this->position;
}
public function next() {
++$this->position;
}
public function valid() {
return isset($this->array[$this->position]);
}
}
例 1. テスト:
echo PHP_EOL . "Custom Seekable Iterator seek Test" . PHP_EOL;
$it = new MySeekableIterator;
$it->seek(1);
try {
$it->seek(10);
echo $it->key() . PHP_EOL;
echo "Is valid? " . (int) $it->valid() . PHP_EOL;
} catch (OutOfBoundsException $e) {
echo $e->getMessage() . PHP_EOL;
echo $it->key() . PHP_EOL; // outputs previous position (1)
echo "Is valid? " . (int) $it->valid() . PHP_EOL;
}
テスト 1 の出力:
Custom Seekable Iterator seek Test
invalid seek position (10)
1
Is valid? 1
例 2:
ネイティブ ArrayIterator::seek の使用
テスト 2 コード:
echo PHP_EOL . "Array Object Iterator seek Test" . PHP_EOL;
$array = array('1' => 'one',
'2' => 'two',
'3' => 'three');
$arrayobject = new ArrayObject($array);
$iterator = $arrayobject->getIterator();
$iterator->seek(1);
try {
$iterator->seek(5);
echo $iterator->key() . PHP_EOL;
echo "Is valid? " . (int) $iterator->valid() . PHP_EOL;
} catch (OutOfBoundsException $e) {
echo $e->getMessage() . PHP_EOL;
echo $iterator->key() . PHP_EOL; // outputs previous position (1)
echo "Is valid? " . (int) $iterator->valid() . PHP_EOL;
}
テスト 2 の出力:
Array Object Iterator seek Test
Seek position 5 is out of range
1
Is valid? 1
例 3:
ネイティブ DirectoryIterator::seek の使用
テスト 3 コード:
echo PHP_EOL . "Directory Iterator seek Test" . PHP_EOL;
$dir_iterator = new DirectoryIterator(dirname(__FILE__));
$dir_iterator->seek(1);
try {
$dir_iterator->seek(500); // arbitrarily high seek position
echo $dir_iterator->key() . PHP_EOL;
echo "Is valid? " . (int) $dir_iterator->valid() . PHP_EOL;
} catch (OutOfBoundsException $e) {
echo $e->getMessage() . PHP_EOL;
echo $dir_iterator->key() . PHP_EOL;
echo "Is valid? " . (int) $dir_iterator->valid() . PHP_EOL;
}
テスト 3 の出力:
Directory Iterator seek Test
90
Is valid? 0
valid()
では、有効な位置を確認するために使用するかどうかを合理的に知るにはどうすればよいでしょうか。また、位置を更新する代わりに Exception がスローされる可能性がseek($position)
あることを予測して、true を返すのでしょうか?seek()
valid()