• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 位置: php 中文手册 -> php 语言

    php 遍历接口

    检测一个类是否可以使用 foreach 进行遍历的接口。

    无法被单独实现的基本抽象接口。相反它必须由 IteratorAggregateIterator 接口实现。

    Note:

    实现此接口的内建类可以使用 foreach 进行遍历而无需实现 IteratorAggregateIterator 接口。

    Note:

    这是一个无法在 PHP 脚本中实现的内部引擎接口。IteratorAggregateIterator 接口可以用来代替它。

    接口摘要

    Traversable{}
    

    这个接口没有任何方法,它的作用仅仅是作为所有可遍历类的基本接口。

    While you cannot implement this interface, you can use it in your checks to determine if something is usable in for each. Here is what I use if I'm expecting something that must be iterable via foreach.
    <?php
      if( !is_array( $items ) && !$items instanceof Traversable )
        //Throw exception here
    ?>
    
    NOTE: While objects and arrays can be traversed by foreach, they do NOT implement "Traversable", so you CANNOT check for foreach compatibility using an instanceof check.
    Example:
    $myarray = array('one', 'two', 'three');
    $myobj = (object)$myarray;
    if ( !($myarray instanceof \Traversable) ) {
      print "myarray is NOT Traversable";
    }
    if ( !($myobj instanceof \Traversable) ) {
      print "myobj is NOT Traversable";
    }
    foreach ($myarray as $value) {
      print $value;
    }
    foreach ($myobj as $value) {
      print $value;
    }
    Output:
    myarray is NOT Traversable
    myobj is NOT Traversable
    one
    two
    three
    one
    two
    three
    The PHP7 iterable pseudo type will match both Traversable and array. Great for return type-hinting so that you do not have to expose your Domain to Infrastructure code, e.g. instead of a Repository returning a Cursor, it can return hint 'iterable':
    <?php
    UserRepository::findUsers(): iterable
    ?>
    Link: http://php.net/manual/en/migration71.new-features.php#migration71.new-features.iterable-pseudo-type
    Also, instead of:
    <?php
      if( !is_array( $items ) && !$items instanceof Traversable )
        //Throw exception here
    ?>
    You can now do with the is_iterable() method:
    <?php
      if ( !is_iterable( $items ))
        //Throw exception here
    ?>
    Link: http://php.net/manual/en/function.is-iterable.php
    Note that all objects can be iterated over with foreach anyway and it'll go over each property. This just describes whether or not the class implements an iterator, i.e. has custom behaviour.
    Actually you can use `Traversable` within your php scripts - you can use it to enforce iterability on user-land objects.
    <?php
    interface Stream implements \Traversable {}
    class InMemoryStream implements IteratorAggregate, Stream
    {
      public function getIterator() {}
    }
    $stream = new InMemoryStream(); 
    ?>
    In case you'd forgot about implementing `IteratorAggregate` or `Iterator` interfaces, fatal error will be raised when instantiating objects in question.
    <?php
    interface Stream implements \Traversable {}
    class InMemoryStream implements Stream {}
    $stream = new InMemoryStream(); // Fatal error: Class InMemoryStream must implement interface Traversable as part of either Iterator or IteratorAggregate in Unknown on line 0
    ?>