spl转换器_使用SPL迭代器,第2部分

spl转换器

In part one of this series I introduced you to some of the SPL Iterators and how to use them. There may be times however when the provided iterators are insufficient for your needs and you’ll want to roll your own custom iterator. Luckily, SPL provides interfaces that will allow you to do just that.

在本系列的第一部分中 ,我向您介绍了一些SPL迭代器以及如何使用它们。 但是,有时有时所提供的迭代器不足以满足您的需求,因此您需要推出自己的自定义迭代器。 幸运的是,SPL提供的界面将使您能够做到这一点。

For an object to be traversable in a foreach loop, PHP requires that it be an instance of Traversable. You cannot however implement this interface directly (though you can use it in instaceof checks); instead you’ll need to implement either SPL’s Iterator or IteratorAggregate interfaces.

为了使对象在foreach循环中可遍历,PHP要求它是Traversable的实例。 但是,您不能直接实现此接口(尽管您可以在instaceof检查中使用它)。 相反,您需要实现SPL的IteratorIteratorAggregate接口。

迭代器 (Iterator)

Iterator allows you to create objects that are are iterated directly or for the creation of external Iterators. It specifies five methods that need to be implemented: rewind(), current(), key(), next(), and valid().

Iterator允许您创建直接迭代的对象或用于创建外部迭代器的对象。 它指定了五个需要实现的方法: rewind()current()key()next()valid()

Assume we have a library of books and we want to be able to iterate over the collection of books in the library. Here’s an example that does so by implementing Iterator:

假设我们有一个图书馆,我们希望能够遍历图书馆中的所有书籍。 这是通过实现Iterator来执行此操作的示例:

<?php
class Library implements Iterator
{
    // an internal pointer to the current position
    // in the dataset
    protected $position = 0;

    // an array of the titles of the books in the library
    protected $books = [
        "Professional PHP Programming",
        "Programming Perl",
        "A Byte of Python",
        "The Ruby Way"
    ];

    // this method takes the pointer back to the beginning
    // of the dataset to restart the iteration
    public function rewind() {
        echo "rewinding <br>";
        $this->position = 0;
    }

    // this method returns the value at the current
    // position of the dataset
    public function current() {
        echo "current <br>";
        return $this->books[$this->position];
    }

    // this should return the current value of the pointer
    public function key() {
        echo "key <br>";
        return $this->position;
    }

    // this method moves the pointer to the next value
    // in the data set
    public function next() {
        echo "next <br>";
        ++$this->position;
    }

    / /this returns a boolean indicating if the there
    // is data at the current position in the dataset
    public function valid() {
        echo "valid <br>";
        return isset($this->books[$this->position]);
    }
}

$library = new Library();
foreach ($library as $key => $value) {
    echo $key . ": " . $value . "<br>";
}

The output of the above code is:

上面代码的输出是:

rewinding 
valid 
current 
key 
0: Professional PHP Programming
next 
valid 
current 
key 
1: Programming Perl
next 
valid 
current 
key 
2: A Byte of Python
next 
valid 
current 
key 
3: The Ruby Way
next 
valid

When the iteration starts, PHP calls the rewind() method to take the pointer back to the beginning of the dataset. It then checks to see if there is valid data at that point by calling valid(). If it receives true, it then calls current() to get the value at that point in the iteration. Since you are asking for the $key in the loop construct, PHP calls the key() method to get the value of the current key. PHP then calls next() to advance the pointer and calls valid() again to check if there is valid data. The cycle continues until valid() returns false.

迭代开始时,PHP调用rewind()方法将指针带回到数据集的开头。 然后,它通过调用valid()来检查此时是否存在有效数据。 如果收到true,则调用current()以获取迭代中该点的值。 由于您在循环构造中要求$key ,因此PHP调用key()方法来获取当前键的值。 然后,PHP调用next()前进指针,并再次调用valid()来检查是否存在有效数据。 循环一直持续到v alid()返回false为止。

Iterator gives you the ability to implement very powerful iterators from scratch and is best suited for creating internal iterators like above. Of course, the example above is simple and is only intended to give you an overview of the required methods and how they work. Ideally, with a dataset such as the one above (an array), you will be better off using IteratorAggregate.

Iterator器使您能够从头开始实现功能非常强大的迭代器,最适合于创建上述内部迭代器。 当然,上面的示例很简单,仅用于概述所需的方法及其工作方式。 理想情况下,使用上面的数据集(一个数组),最好使用IteratorAggregate

IteratorAggregate (IteratorAggregate)

IteratorAggregate requires you to implement a single method, getIterator(). This method is required to return an external iterator which will be used for iteration. Rewriting the example above to use IteratorAggregate gives us:

IteratorAggregate要求您实现一个方法getIterator() 。 需要此方法来返回将用于迭代的外部迭代器。 重写上面的示例以使用IteratorAggregate给我们:

<?php
class Library implements IteratorAggregate
{
    protected $books = [
        "Professional PHP Programming",
        "Programming Perl",
        "A Byte of Python",
        "The Ruby Way"
    ];

    // return an Iterator of your data
    public function getIterator() {
        echo "getIterator <br>";
        return new ArrayIterator($this->books);
    }
}

$library = new Library();
foreach($library as $key => $value) {
    echo $key . ": " . $value . "<br>";
}

The output of the above code is:

上面代码的输出是:

getIterator 
0: Professional PHP Programming
1: Programming Perl
2: A Byte of Python
3: The Ruby Way

At the start of the iteration, PHP calls getIterator() which returns an iterator, in this case SPL’s ArrayIterator. PHP then makes all the appropriate calls on that iterator. Basically, you hand over the data to the external iterator which does all the work for you while you sit back and relax.

在迭代开始时,PHP调用getIterator()返回一个迭代器,在本例中为SPL的ArrayIterator 。 然后,PHP在该迭代器上进行所有适当的调用。 基本上,您将数据移交给外部迭代器,当您坐下来放松时,它将为您完成所有工作。

Since both interfaces provide the same functionality, knowing whether to use Iterator or IteratorAggregate can sometimes be tricky. As a general rule of thumb, you should use Iterator when you need to actually define the behavior of your iterator from scratch because IteratorAggregate is not a good fit.

由于两个接口都提供相同的功能,因此有时要知道使用Iterator还是IteratorAggregate可能很棘手。 作为一般经验法则,当您需要从头开始实际定义迭代器的行为时,应使用Iterator ,因为IteratorAggregate不太适合。

摘要 (Summary)

I’ve introduced you to two interfaces that allow you to create your own iterators in this article. Hopefully, you understand how easy it is to create your very own iterators and are ready to add this cool feature of SPL to your arsenal. Of course, if you feel I missed something or erred in any way, or even just have something to share, please don’t hesitate to let me know in the comments!

在本文中,我向您介绍了两个接口,这些接口使您可以创建自己的迭代器。 希望您了解创建自己的迭代器有多么容易,并准备将SPL的这一出色功能添加到您的武器库中。 当然,如果您觉得我错过了任何东西或以任何方式犯了错误,甚至只是想分享一些东西,请随时在评论中让我知道!

Image via Mushakesa / Shutterstock

图片来自Mushakesa / Shutterstock

翻译自: https://www.sitepoint.com/using-spl-iterators-2/

spl转换器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值