所以我不确定这是否是 PHP 的错误设计,或者是否有一个可以理解的逻辑来处理同一接口的不一致结果。
SeekableIterator 接口有两种方法 (seek
和valid
),它们或者相互冲突,或者应该相互一致地工作,但我看到了两者。
该接口的文档说seek
应该抛出类 OutOfBoundsException 的异常,但这似乎否定了valid
除非迭代器位置valid
在抛出异常(显然必须被捕获)之前更新(使返回 false)的有用性。
三个测试示例
示例 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()
来确认有效位置,seek($position)
同时还预期seek()
可能会抛出异常而不是更新位置,从而valid()
返回 true?