【问题标题】:PHP Iterator like mysql iterator?PHP迭代器像mysql迭代器?
【发布时间】:2013-02-03 12:43:21
【问题描述】:

我已经从 SPL 迭代器扩展和实现了。
但如果我想使用它,我应该在foreach 上使用它。
我尝试在while 中使用它,如下所示:

$news = new testClass();

while( $row = $news )
    echo $row["name"];

它将创建一个无限循环!
但是对于foreach,它工作正常!

这是我班上的佼佼者:

class testClass implements \Iterator

错在哪里?

【问题讨论】:

  • 使用while 循环更像是一种C 风格的迭代器,而不是您所想的迭代器。您需要实现Iterator's methods,然后它应该与 foreach 循环一起工作。
  • 您是否尝试迭代 $news 对象中的公共属性?

标签: php iterator


【解决方案1】:

拳头,勇敢地使用SPL 类来解决这种“标准”问题。我经常看到缺乏经验/草率的开发人员(甚至是优秀的开发人员根本不提前考虑)在这些类型的情况下重新发明轮子。

您遗漏了一些关于实现iterator 接口的非常重要的细节。

请参阅PHP:Iterator - Manual 了解更多信息,以及下面的参考实现。

首先,您需要实现rewind, current, key, next, and valid 函数。参考实现如下所示:

class myIterator implements Iterator {
    private $position = 0;
    private $array = array(
        "firstelement",
        "secondelement",
        "lastelement",
    );  

    public function __construct() {
        $this->position = 0;
    }

    function rewind() {
        var_dump(__METHOD__);
        $this->position = 0;
    }

    function current() {
        var_dump(__METHOD__);
        return $this->array[$this->position];
    }

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

    function next() {
        var_dump(__METHOD__);
        ++$this->position;
    }

    function valid() {
        var_dump(__METHOD__);
        return isset($this->array[$this->position]);
        }
    }
)

遍历该实现的代码如下所示:

$it = new myIterator;

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

【讨论】:

  • +1!感谢您的回答。我已经有这种风格了。如果你回答我的问题,我说这是我班上的佼佼者!
  • 我注意到了,但它并没有告诉我你已经实现了必要的功能。那么,您的问题的答案包含在示例代码的第二位(使用 foreach 而不是 for)中。
【解决方案2】:

foreach 是遍历所有元素的语言结构。 while 执行代码块,直到给定条件为真。要使其工作,您必须使用自己的函数来检查有效键并返回当前元素。

【讨论】:

    【解决方案3】:

    最后我创建了一个简单的例子:

    <?php
    
    /**
     * @author Soroush Khosravi
     * @copyright 2013
     */
    class _Iterator
    {
        private $array;
    
        public function setArray(array $data)
        {
            $this->array = $data;
        }
    
        public function reader()
        {
            if (is_null($this->array))
                return false;
    
            $elem = array_shift($this->array);
            if (count ($this->array) > 0)
                return $elem;
            return false;
        }
    }
    
    Class child extends _Iterator
    {
        function execute()
        {
            $this->setArray(array(1,2,3,4,5,6));
            return $this;
        }
    }
    $obj = new child;
    $obj = $obj->execute();
    while($row = $obj->reader())
        echo $row;
    
    ?>
    

    【讨论】:

    • 无需回答您自己的问题。请记住,对于数组中的任何虚假值,这都会失败(即尝试将 0 放在 3 和 4 之间),所以最好坚持使用foreach
    • @dev-null-dweller 我不记得我问过foreach!我一直在寻找这个表格,现在这是我的答案,我认为这是真的:)
    • 我只是说你可能对这个结构的某些值有问题,仅此而已。
    • 无论您正在寻找何种形式的答案,使用 foreach 都是解决此问题的更好、更不容易出错的方法。在这种情况下,不使用 foreach 就像使用字符数组而不是字符串一样。用一个没有经过深思熟虑的答案来回答你自己的问题是愚蠢的。
    • 感谢所有 cmets :x 但我将它用于 mysql,我认为数组上的任何元素都不会是 false 或等效于 false...
    猜你喜欢
    • 2013-08-30
    • 1970-01-01
    • 2010-10-27
    • 2018-05-16
    • 2017-11-11
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 2016-10-22
    相关资源
    最近更新 更多