PHP Conference Japan 2024

IteratorIterator 类

(PHP 5 >= 5.1.0,PHP 7,PHP 8)

简介

此迭代器包装器允许将任何Traversable转换为 Iterator。 重要的是要了解大多数未实现迭代器的类都有其原因,因为它们很可能不允许使用完整的迭代器功能集。 如果是这样,应提供技术来防止误用,否则可能会出现异常或致命错误。

类概要

class IteratorIterator implements OuterIterator {
/* 方法 */
public __construct(Traversable $iterator, ?string $class = null)
public current(): mixed
public key(): mixed
public next(): void
public rewind(): void
public valid(): bool
}

注释

注意:

此类允许通过 __call 魔术方法访问内部迭代器的方法。

目录

添加注释

用户贡献的注释 4 条注释

sven at rtbg dot de
9 年前
这个迭代器基本上只是另一个迭代器的包装器。 它不做任何花哨的事情,它只是将 rewind()、next()、valid()、current() 和 key() 的任何调用转发到内部迭代器。 此内部迭代器可以通过 getInnerIterator() 获取。

一种特殊情况:当传递一个 IteratorAggregate 对象时,将调用该对象的 getIterator() 方法,并且将迭代该迭代器,并且在调用 getInnerIterator() 时也将返回该迭代器。

此类可以扩展,因此它是您自己的类的理想构建块,这些类只想修改一两个迭代器方法,而不是全部修改。

想要修剪 current() 方法返回的字符串?

<?php

class TrimIterator extends IteratorIterator
{
public function
current() {
return
trim(parent::current());
}
}

$innerIterator = new ArrayIterator(array('normal', ' trimmable '));

$trim = new TrimIterator($innerIterator);

foreach (
$trim as $key => $value) {
echo
"Key:\n";
var_dump($key);
echo
"Value:\n";
var_dump($value);
echo
"---next---";
}
?>

输出


int(0)

string(6) "normal"
---next---键
int(1)

string(9) "trimmable"
---next---
max-p at max-p dot me
8 年前
对于任何想要尽可能地模拟 foreach 行为以处理某些挑剔的可遍历对象(不使用 foreach)的人来说,一个小小的提示

- 在开始迭代之前,将调用 rewind()。
- 对于每次迭代,以下方法都会在迭代器上调用
- valid()
- current()
- key()
- next()

这样说起来似乎很傻,但在我的用例中,我需要将可遍历的数据库结果游标转换为过程式游标(hasNext + fetchArray)以实现向后兼容性,并且驱动程序要求每个函数都按适当的顺序调用。
thomas at gielfeldt dot dk
7 年前
IteratorIterator::current() 不会调用内部迭代器的 current() 方法。

内部迭代器的 current() 方法在 rewind() 和 next() 上被调用(并缓存)。 key() 和 valid() 也是如此。

示例
<?php

$i
= new ArrayIterator(range(1,10));
$i = new IteratorIterator($i);
iterator_to_array($i); // 查找到底部
print "Valid: " . $i->valid() . "\n";
$i->append('test');
print
"Valid: " . $i->valid() . "\n";
print
"Current: " . $i->current() . "\n";

?>

输出

有效
有效
当前

然而
<?php

$i
= new ArrayIterator(range(1,10));
iterator_to_array($i); // 移到末尾
print "有效: " . $i->valid() . "\n";
$i->append('test');
print
"有效: " . $i->valid() . "\n";
print
"当前: " . $i->current() . "\n";
?>

输出

有效
有效: 1
当前: test

原因在于 IteratorIterator 调用 current()、key() 和 valid() 的方式,如上所述。
wallacemaxters at gmail dot lcom
8 年前
另一个 IteratorIterator 效率的例子是一个用于迭代器实现枚举的小类。

示例

<?php

class Enumerator extends IteratorIterator
{
/**
* 枚举器的初始值
* @param int
*/
protected $start = 0;

/**
* @param int
*/
protected $key = 0;

/**
* @param Traversable $iterator
* @param scalar $start
*/
public function __construct(Traversable $iterator, $start = 0)
{
parent::__construct($iterator);

$this->start = $start;

$this->key = $this->start;
}

public function
key()var_dump
{
return
$this->key;
}

public function
next()
{
++
$this->key;

parent::next();
}

public function
rewind()
{
$this->key = $this->start;

parent::rewind();
}

}
?>

这将产生

<?php

$enumerator
= new Enumerator(
new
ArrayIterator(['php', 'java', 'python']); 7000
);

print_r(iterator_to_array($enumerator));

/*
* array(3) {
7000 => 'php',
7001 => 'java',
7002 => 'python'
}
*/

?>
To Top