【问题标题】:configure own iterator for class php?为类 php 配置自己的迭代器?
【发布时间】:2015-05-26 17:51:43
【问题描述】:

我有一个班级 Foo,我需要做:

$foo = new Foo();
foreach($foo as $value)
{
    echo $value;
}

并定义我自己的方法来迭代这个对象,例如:

class Foo
{
    private $bar = [1, 2, 3];
    private $baz = [4, 5, 6];


    function create_iterator()
    {
        //callback to the first creation of iterator for this object
        $this->do_something_one_time();
    }

    function iterate()
    {
        //callback for each iteration in foreach
        return $this->bar + $this->baz;
    }
}

我们可以这样做吗?怎么样?

【问题讨论】:

    标签: php class iterator


    【解决方案1】:

    你需要实现Iterator接口。

    class Foo implements Iterator {

    您应该查看内置接口:

    http://php.net/manual/en/reserved.interfaces.php

    【讨论】:

    • +1,但请注意:这些仅适用于 PHP5。如果您不使用 PHP5,那么是时候升级了。已经10多年了。
    • @Matrix 请澄清您的问题。如果您实现迭代器或迭代器聚合接口,那么您将能够遍历您的对象。这就是你想要完成的事情。
    【解决方案2】:

    您需要实现\Iterator\IteratorAggregate 接口来实现。

    您尝试使用 \IteratorAggregate 和 \Iterator 接口实现的简单示例(我省略了 \Iterator 实现细节,但您可以使用 PHP 文档查看它们的工作原理):

    class FooIterator implements \Iterator
    {
        private $source = [];
    
        public function __construct(array $source) 
        {
            $this->source = $source;
            // Do whatever else you need
        }
    
        public function current() { ... }
        public function key() { ... }
        public function next() 
        {
            // This function is invoked on each step of the iteration
        }
        public function rewind() { ... }
        public function valid() { ... }
    }
    
    
    class Foo implements \IteratorAggregate
    {
        private $bar = [1, 2, 3];
        private $baz = [4, 5, 6];
    
        public function getIterator()
        {
            return new FooIterator(array_merge($this->bar, $this->baz));
        }
    }
    
    $foo = new Foo();
    
    foreach ($foo as $value) {
        echo $value;
    }
    

    【讨论】:

    • 好的,但是我可以控制在创建迭代器时放置我自己的代码吗?如何/在哪里放置我的代码?
    • 我已经更新了我的答案以符合您的要求——如果我理解正确的话
    • 是的,但是为什么不用自定义子类覆盖 ArrayIterator 并只覆盖构造函数呢?我会测试的,谢谢。
    • 因为继承是邪恶的? :p 无论哪种解决方案都适合您,我的回答只是一种做事方式,并向您展示如何使用这两种界面。
    • 继承是 POO 的概念。这是一种更好的方法,我不需要重新实现所有方法,我只需像这样覆盖:class MyIterator extends ArrayIterator { public function __construct($array=[]) { parent::__construct($array); echo 'test'; //DO what I need here } } 就可以了。
    猜你喜欢
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    • 2015-02-12
    • 2010-09-13
    • 2011-02-20
    • 1970-01-01
    相关资源
    最近更新 更多