当我们需要SPL IteratorAggregate?

时间:2013-11-17 10:52:51

标签: php spl

我在PHP manual中阅读了IteratorAggregate的示例。我尝试删除IteratorAggregate接口,但输出与实现的类似。

<?php    
    class myData {
        public $property1 = "Public property one";
        public $property2 = "Public property two";
        public $property3 = "Public property three";

        public function __construct() {
            $this->property4 = "last property";
        }
    }

    $obj = new myData;

    foreach($obj as $key => $value) {
        var_dump($key, $value);
        echo "\n";
    }

输出:

string(9) "property1"
string(19) "Public property one"

string(9) "property2"
string(19) "Public property two"

string(9) "property3"
string(21) "Public property three"

string(9) "property4"
string(13) "last property"

我想知道我们何时应该实现IteratorAggregate接口?为什么输出是相同的?

2 个答案:

答案 0 :(得分:5)

手册页中的示例并不是很好,正是因为您在此处描述的内容。示例类实现IteratorAggregate并执行此操作:

public function getIterator() {
    return new ArrayIterator($this);
}

ArrayIterator,当提供对象时,只提供对象的公共属性。正如您所演示的那样,只需在原始对象上执行foreach即可完成此操作。

一个更有用的例子是,如果我们想要反映不同的值选择。例如,假设所有这些元素都是private,我们不想发送$property3

class myData implements IteratorAggregate {
    private $property1 = "Public property one";
    private $property2 = "Public property two";
    private $property3 = "Public property three";

    public function __construct() {
        $this->property4 = "last property";
    }

    public function getIterator() {
        return new ArrayIterator(array(
            'property1' => $this->property1,
            'property2' => $this->property2,
            'property4' => $this->property4
        ));
    }
}

$obj = new myData;

foreach($obj as $key => $value) {
    var_dump($key, $value);
    echo "\n";
}

这将构造一个包含所需属性的迭代器,而不是所有属性。

你可以用这种方式构造任何迭代器,甚至是与类的属性完全无关的迭代器。通常,最好的方法是实现Iterator,但有时候如果能够更快地构造一个新的迭代器对象并使用getIterator指向它。

答案 1 :(得分:3)

现在更改您的代码以使用PRIVATE或PROTECTED属性,然后重试......

当前效果是,如果迭代具有公共属性的对象,则将对象强制转换为数组,从而使所有公共属性成为键和值。这就是你拥有的。

使用interator接口,您可以迭代公共属性中不可用的值。它们也可能只是在您访问它们时生成,即从数据库中获取。