Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP中带OOP的迭代器的一般帮助_Php_Oop_Iterator_Iteration - Fatal编程技术网

PHP中带OOP的迭代器的一般帮助

PHP中带OOP的迭代器的一般帮助,php,oop,iterator,iteration,Php,Oop,Iterator,Iteration,我刚刚从一本书中了解了PHP中的OOP,关于迭代器和迭代的部分让我感到困惑 据我所知,我认为为了循环遍历对象的属性,需要实现内置类迭代器。然后实现IteratorAggregate接口并在中创建getIterator方法。然而,我目前对这些元素所扮演的角色以及它们需要以何种格式编写感到困惑。换句话说,我只是想找一个简单的(简单的英语)解释这些概念和一个简单的例子。任何帮助都将不胜感激 并感谢您的时间和帮助提前 对于基本功能,您只需要实现迭代器,并为倒带、有效、键、当前和下一步方法添加相关功能。请

我刚刚从一本书中了解了PHP中的OOP,关于迭代器和迭代的部分让我感到困惑

据我所知,我认为为了循环遍历对象的属性,需要实现内置类迭代器。然后实现IteratorAggregate接口并在中创建getIterator方法。然而,我目前对这些元素所扮演的角色以及它们需要以何种格式编写感到困惑。换句话说,我只是想找一个简单的(简单的英语)解释这些概念和一个简单的例子。任何帮助都将不胜感激


并感谢您的时间和帮助提前

对于基本功能,您只需要
实现迭代器
,并为
倒带
有效
当前
下一步
方法添加相关功能。请参见下面的示例:

  /**
   * Awesome
   *
   * Do awesome stuff
   */
  final class Awesome implements Iterator
  {

    /**
     * An array of data
     *
     * @access private
     * @var array $_data
     */
    private $_data;

    /**
     * Store the initial data
     *
     * @access public
     * @param array $data
     */
    public function __construct(array $data = array())
    {
      $this->_data = $data;
    }

    /**
     * Rewind the iterator
     *
     * @access public
     */
    public function rewind()
    {
      reset($this->_data);
    }

    /**
     * Validate the existence of the next element
     *
     * @access public
     * @return boolean
     */
    public function valid()
    {
      return isset($this->_data[$this->key()]);
    }

    /**
     * Return the current key
     *
     * @access public
     * @return integer
     */
    public function key()
    {
      return key($this->_data);
    }

    /**
     * Return the current value
     *
     * @access public
     * @return mixed
     */
    public function current()
    {
      return current($this->_data);
    }

    /**
     * Increment the iteration index
     *
     * @access public
     */
    public function next()
    {
      next($this->_data);
    }

  }

  // Instantiate a new Awesome object
  $awesome = new Awesome(array('Michael', ' ', 'Rushton', ' ', 'is', ' ', 'awesome', '!'));

  // Iterate over the awesome object and output a universal truth
  foreach ($awesome as $almost_awesome)
  {
    echo $almost_awesome;
  }
如果您希望迭代对象的属性,只需将
\u构造更改为:

/**
 * Construct the object
 *
 * @access public
 */
public function __construct()
{

  // Get the properties
  $object_vars = get_object_vars($this);

  // Unset the data reference
  unset($object_vars['_data']);

  // Set the data
  $this->_data = $object_vars;

}

您想要循环的东西必须实现。但是,您不能直接实现
可遍历
;您必须实现它的一个子类型。您将如何操作取决于对象的使用方式

如果您愿意,您可以直接实现。如果你的类型已经是一个只向前发送的列表,那么这就足够了。如果您决定构建迭代器,您将有5种方法要实现:

  • current
    ,检索当前位置的值
  • ,检索当前位置的键
  • next
    ,前进到下一个位置
  • 倒带
    ,将当前位置重置为第一个位置;及
  • valid
    ,如果迭代从正在迭代的内容列表的末尾脱落,则返回
    false
PHP在迭代过程中调用这些方法。具体来说,假设您有这样的代码:

foreach ($it as $key => $value) {
    doStuffWith($key, $value);
}
这相当于以下内容:

for ($it->rewind(); $it->valid(); $it->next()) {
    $value = $it->current();
    $key = $it->key(); // only if the foreach has a `$key =>`

    doStuffWith($key, $value);
}
基本上,您只需要构建一个类型,
实现迭代器
,并正确地响应大致按该顺序调用的那些方法。理想情况下,在这两者之间也可能发生一些事情……但这通常不是问题,除非你在传递引用

如果您不需要自定义迭代,您可以只实现,并返回一个现有的迭代器类型(如果它能够满足您的需要)。(例如,如果您想允许在内部数组上循环,那么已经有了一个为该作业制作的
ArrayIterator
。无需自行滚动。)对于
IteratorAggregate
,您只需实现
getIterator
,它返回可遍历的内容。如果您的某个对象已经可以被其中一个对象遍历,或者可以轻松简化为数组或其他对象,那么这是一个更好的解决方案

如果在迭代器聚合上调用上述相同的循环,则相当于

foreach ($it->getIterator() as $key => $value) {
    doStuffWith($key, $value);
}
getIterator()
必须返回
Iterator
的实现或一些基本的可遍历内容,如数组


对于Java风格的迭代器,您可以构建一个迭代器子类型,该子类型可以记住其位置并在集合上循环,然后在集合上实现以返回迭代器类型的实例。

谢谢。非常有用。特别是关于可遍历的使用。我的教科书指出,实现Transversable会产生一个致命的错误,只是不这样做。然而,现在很明显,您无法直接实现!谢谢@user1216849:是的……他们可能认为必须有一种方法来输入提示“stuff you can
foreach
over”或其他什么,所以必须有一个共同的类型。但仅仅说“你可以为每个人
foreachme”是不够的。您必须提供这样做的方法,而Traversable不能做到这一点;它将这留给它的子类型。感谢Michael提供了这个著名的示例!!!!我同意输出!:干杯