【问题标题】:Why does PHP have iterator objects?为什么 PHP 有迭代器对象?
【发布时间】:2012-06-20 12:39:22
【问题描述】:

我今天偶然发现了这个PHP: Iterators 页面,我想知道为什么甚至需要这些课程。我想假设它们是有目的的,否则它们就不会出现在 PHP 中。当已经有非常简单的方法可以做到这些时,我很难看到这些项目的好处。

PHP 在成为一种更受人尊敬/面向对象的编程语言方面是否犯了错误?或者这样做真的有好处吗?

PHP comment on the ArrayIterator 中找到了一个很好的例子,说明有两种方法可以做到这一点:

<?php
$fruits = array(
    "apple" => "yummy",
    "orange" => "ah ya, nice",
    "grape" => "wow, I love it!",
    "plum" => "nah, not me"
);
$obj = new ArrayObject( $fruits );
$it = $obj->getIterator();

// How many items are we iterating over?
echo "Iterating over: " . $obj->count() . " values\n";

// Iterate over the values in the ArrayObject:
while( $it->valid() ) {
    echo $it->key() . "=" . $it->current() . "\n";
    $it->next();
}

// The good thing here is that it can be iterated with foreach loop

foreach ($it as $key=>$val)
echo $key.":".$val."\n";

/* Outputs something like */

Iterating over: 4 values
apple=yummy
orange=ah ya, nice
grape=wow, I love it!
plum=nah, not me

?>

【问题讨论】:

  • 为什么他们应该存在?数组(在 PHP 的意义上)非常有限。只需查看现有的迭代器。具体的描述了一些常见的用例(例如递归的)。
  • 也许this thread 中的解释有点帮助,尽管这是关于 java 的

标签: php iterator


【解决方案1】:

迭代器包含在 PHP 中是因为它允许您对任意对象使用通用语言结构(例如 foreach),而不是仅限于循环遍历数组等内置对象。强制对象将其内部状态转换为数组供您迭代是一件麻烦事(并且会破坏封装),并且对于大型数据集可能会使您的系统内存不足。通过让对象本身仅在请求时返回单个元素,可迭代对象可以让您解决这两个问题。

【讨论】:

    【解决方案2】:

    您的示例并不是使用 Iterator 对象的真正原因。在大多数情况下,Iterator 对象用于迭代一个类并将一个类直接用作迭代器。

    http://php.net/manual/de/class.iterator.php

    这是一个简短的例子。

    当你有一个数组时,在数组上创建一个 foreach 真的很容易。

    【讨论】:

      【解决方案3】:

      对于我的示例,我不会将答案限制为 Iterator,还包括 Traversable。

      看看 SimpleXML(SimpleXMLElementSimpleXMLIterator)。

      非常有用且易于使用,允许您将 XML 转换为可以迭代/遍历的对象,因为它扩展了提供该功能的类。我已经通过相当一部分的 XML 找到了自己的方式,并且很高兴它不必重新发明轮子来提供它。我相信还有更多关于它们的使用和存在原因的例子,但这些是第一个弹出的例子,我立即从中受益,它们不是数组。

      【讨论】:

        【解决方案4】:

        您可能会遇到希望将IteratorAggregate 实现到类中的实例,因此您可以迭代私有成员而无需将其公开,或创建公共函数:

        class BaseballTeams implements IteratorAggregate
        {
            private $teams;
        
            public function __construct( )
            {
                $this->teams = explode( ',', "Tigers,Cubs,Orioles,Mariners,Yankees,Blue Jays,Marlins" );
            }
        
            public function getIterator( )
            {
                return new ArrayIterator( $this->teams );
            }
        }
        

        现在,您可以循环访问私有 $teams 成员,如下所示:

        $baseball = new BaseballTeams( );
        
        foreach ( $baseball as $n => $t )
        {
            echo "<p>Team #$n: $t</p>";
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-16
          • 2015-12-16
          • 2018-08-16
          • 1970-01-01
          • 2021-02-03
          • 2020-04-14
          • 2020-10-22
          • 1970-01-01
          相关资源
          最近更新 更多