Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】LimitIterator::rewind()メソッドの使い方

rewindメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

rewindメソッドは、LimitIteratorオブジェクトを反復処理範囲の先頭要素に巻き戻す処理を実行するメソッドです。LimitIteratorクラスは、既存のイテレータオブジェクトに対して、指定された開始位置(オフセット)と要素数に基づいた一部分のビューを提供するものです。このrewindメソッドが呼び出されると、まず内部で保持している元のイテレータ自体を先頭に巻き戻します。その後、LimitIteratorのコンストラクタで指定されたオフセット値の分だけ、内部イテレータのポインタを自動的に前進させます。これにより、LimitIteratorとしての現在位置は、反復処理の対象となる範囲の最初の要素を正確に指す状態になります。通常、このメソッドはforeachループが開始される際にPHPエンジンによって内部的に呼び出されるため、開発者が明示的に呼び出す機会は多くありません。このメソッドは値を返しません。

構文(syntax)

1<?php
2
3$iterator = new LimitIterator(new ArrayIterator(['a', 'b', 'c', 'd']), 1, 2);
4
5// イテレータを反復処理の開始位置に戻します。
6$iterator->rewind();
7
8?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

PHP LimitIterator で巻き戻し可能なジェネレータを扱う

1<?php
2
3declare(strict_types=1);
4
5/**
6 * IteratorAggregate を実装して、巻き戻し可能なジェネレータを提供します。
7 * 
8 * 通常のジェネレータは一度しか反復処理できませんが、このクラスでラップすることで、
9 * foreach ループのたびに新しいジェネレータが生成され、何度でも反復処理が可能になります。
10 */
11class RewindableGenerator implements IteratorAggregate
12{
13    public function __construct(private int $start, private int $count)
14    {
15    }
16
17    /**
18     * 新しいジェネレータイテレータを返します。
19     * このメソッドは foreach ループの開始時などに呼び出されます。
20     * 
21     * @return Traversable<int>
22     */
23    public function getIterator(): Traversable
24    {
25        for ($i = 0; $i < $this->count; $i++) {
26            yield $this->start + $i;
27        }
28    }
29}
30
31// 1から10までの数値を生成する、巻き戻し可能なジェネレータを作成します。
32$rewindableGenerator = new RewindableGenerator(1, 10);
33
34// LimitIterator を使用して、3番目(オフセット2)から5個の要素に範囲を制限します。
35// 対象: 3, 4, 5, 6, 7
36$limitIterator = new LimitIterator($rewindableGenerator, 2, 5);
37
38// 1回目のループ
39// foreach が開始されると、LimitIterator::rewind() が内部的に呼び出されます。
40// これにより、getIterator() がコールされ、新しいジェネレータが生成されます。
41echo "1回目のループ:\n";
42foreach ($limitIterator as $number) {
43    echo $number . " ";
44}
45echo "\n\n";
46
47// 2回目のループ
48// もう一度 foreach を実行します。
49// LimitIterator::rewind() が再度呼び出され、新しいジェネレータが再び生成されるため、
50// 問題なく最初から反復処理を再開できます。
51echo "2回目のループ:\n";
52foreach ($limitIterator as $number) {
53    echo $number . " ";
54}
55echo "\n";
56
57?>

LimitIterator::rewindは、イテレータを最初の要素に巻き戻すためのメソッドです。このメソッドは引数を取らず、何も値を返しません。開発者が直接呼び出すことは少なく、foreachループが開始される際にPHPの内部で自動的に呼び出されるのが一般的です。

サンプルコードでは、指定した範囲の数値を生成するRewindableGeneratorLimitIteratorで扱っています。1回目のforeachループが始まると、まずLimitIterator::rewindが内部で実行されます。これにより、元となるRewindableGeneratorgetIteratorメソッドが呼び出され、新しいジェネレータが生成されて反復処理が開始されます。

ループが終了した後、2回目のforeachが実行される際も同様です。再びrewindメソッドが呼び出され、新しいジェネレータが生成されるため、イテレータは先頭に「巻き戻された」かのように振る舞い、問題なく最初から反復処理を再開できます。このように、rewindはイテレータを繰り返し利用可能にするための重要な役割を担っています。

このサンプルコードの重要な点は、LimitIterator自体がジェネレータを巻き戻す機能を持つわけではないことです。foreachループが開始されるとLimitIterator::rewind()が内部で呼び出されますが、このとき、ラップされているRewindableGeneratorクラスがIteratorAggregateを実装しているため、そのgetIterator()メソッドが実行されます。これにより毎回新しいジェネレータが生成されるため、何度でも最初から反復処理ができます。もしIteratorAggregateを使わずに通常の巻き戻し不可能なジェネレータを直接LimitIteratorに渡した場合、2回目以降のループは期待通りに動作しないため注意が必要です。

LimitIterator::rewind() で配列を巻き戻す

1<?php
2
3/**
4 * LimitIterator::rewind() の動作を示すサンプルコードです。
5 *
6 * LimitIteratorは、既存のイテレータ(この例では配列をラップしたArrayIterator)の
7 * 一部分だけを反復処理するためのイテレータです。
8 * rewind()メソッドは、このイテレータを範囲内の最初の要素に巻き戻します。
9 * foreachループが始まる際には暗黙的に呼び出されますが、
10 * 明示的に呼び出してイテレータの位置をリセットすることもできます。
11 */
12function demonstrateLimitIteratorRewind(): void
13{
14    // 元となる配列データ
15    $fruits = [
16        'a' => 'Apple',
17        'b' => 'Banana',
18        'c' => 'Cherry',
19        'd' => 'Date',
20        'e' => 'Elderberry'
21    ];
22
23    // 配列を反復処理可能にするためにArrayIteratorを作成します
24    $arrayIterator = new ArrayIterator($fruits);
25
26    // ArrayIteratorを使い、オフセット1から3つの要素に限定したLimitIteratorを作成します
27    // これにより 'Banana', 'Cherry', 'Date' のみが対象となります
28    $limitIterator = new LimitIterator($arrayIterator, 1, 3);
29
30    echo "--- 1回目のループ ---" . PHP_EOL;
31    // foreachでループ処理すると、最初にrewind()が自動で呼ばれ、
32    // 範囲内の最初の要素から処理が始まります。
33    foreach ($limitIterator as $key => $value) {
34        echo "[{$key}] => {$value}" . PHP_EOL;
35    }
36
37    echo PHP_EOL;
38
39    // ループ後、イテレータの内部ポインタは終端にあります。
40    // valid()はイテレータが有効な位置を指しているか確認します。
41    echo "ループ後の状態: " . ($limitIterator->valid() ? '有効' : '無効') . PHP_EOL;
42
43    // rewind()メソッドを明示的に呼び出して、イテレータを先頭に巻き戻します。
44    echo "LimitIterator::rewind() を呼び出します..." . PHP_EOL;
45    $limitIterator->rewind();
46
47    echo "rewind()後の状態: " . ($limitIterator->valid() ? '有効' : '無効') . PHP_EOL;
48    echo "rewind()後の最初の要素: [{$limitIterator->key()}] => {$limitIterator->current()}" . PHP_EOL;
49
50    echo PHP_EOL;
51
52    echo "--- 2回目のループ ---" . PHP_EOL;
53    // rewind()されたため、再度ループ処理が可能になります。
54    foreach ($limitIterator as $key => $value) {
55        echo "[{$key}] => {$value}" . PHP_EOL;
56    }
57}
58
59// 関数を実行して結果を表示します
60demonstrateLimitIteratorRewind();

LimitIterator::rewind()は、LimitIteratorオブジェクトの内部ポインタを、指定された範囲の最初の要素に巻き戻すためのメソッドです。LimitIteratorは、配列のような繰り返し処理が可能なデータの中から、一部分だけを切り出して順番に処理したい場合に利用します。

サンプルコードでは、まず果物の配列からArrayIteratorを作成し、それを元に2番目の要素から3つ分('Banana', 'Cherry', 'Date')に限定したLimitIteratorを生成しています。

1回目のforeachループが始まる際、PHPは内部で自動的にrewind()を呼び出すため、指定範囲の先頭である 'Banana' から処理が開始されます。ループが終了すると、イテレータは範囲の終端に達しているため、そのままでは再度ループ処理を行うことはできません。そこで$limitIterator->rewind()を明示的に呼び出すことで、イテレータの位置を再び範囲の先頭にリセットします。これにより、2回目のforeachループでも同じ要素を最初から処理することが可能になります。

このメソッドは引数を必要とせず、何も値を返しません(戻り値はなし)。その役割は、イテレータの内部状態を初期位置に戻すことだけです。

LimitIterator::rewind()は、イテレータを指定した範囲の先頭に巻き戻すメソッドです。通常、foreachループを開始する際に自動的に呼び出されるため、自分で記述する必要はほとんどありません。このメソッドを明示的に呼び出すのは、一度ループ処理を終えて終端に達したイテレータを、もう一度最初から使いたい特別な場合です。注意点として、rewind()は元の配列全体の先頭ではなく、LimitIteratorのコンストラクタで指定したオフセット位置(サンプルでは1番目の'Banana')に戻します。範囲外のデータには影響しないことを理解しておくことが重要です。

関連コンテンツ