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

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

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

作成日: 更新日:

基本的な使い方

『rewindメソッドは、RecursiveIteratorIteratorオブジェクトにおけるイテレータの内部ポインタを最初の要素に巻き戻す処理を実行するメソッドです。このメソッドは、PHPのIteratorインターフェースで定められた要件の一つであり、繰り返し処理を開始点にリセットする役割を担います。foreach構文でイテレータを処理する場合、ループの開始時にPHPエンジンによってこのメソッドが暗黙的に呼び出されるため、通常は開発者が意識して呼び出す必要はありません。しかし、一度ループ処理を終えたイテレータを、再度最初から処理したいといった特定の状況下で明示的に使用することがあります。RecursiveIteratorIteratorの文脈では、このメソッドを呼び出すことで、再帰的な構造を持つデータセット全体の走査を、再び一番最初の要素から開始できる状態にリセットします。このメソッドに引数はなく、戻り値もありません。

構文(syntax)

1<?php
2// public RecursiveIteratorIterator::rewind(): void
3
4// RecursiveIteratorIterator のインスタンスを作成します
5$arrayIterator = new RecursiveArrayIterator(['a', ['b', 'c']]);
6$iterator = new RecursiveIteratorIterator($arrayIterator);
7
8// イテレータを最初の要素に巻き戻します
9$iterator->rewind();

引数(parameters)

引数なし

引数はありません

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

PHP RecursiveIteratorIterator::rewind する例

1<?php
2
3declare(strict_types=1);
4
5/**
6 * RecursiveIteratorIterator::rewind の動作を示すクラス
7 * 
8 * このクラスは、巻き戻し可能なイテレータを RecursiveIteratorIterator で
9 * 複数回走査できることを示します。これにより、foreach ループが
10 * 内部で rewind() メソッドを呼び出す挙動を間接的に確認できます。
11 */
12class RewindableIteratorExample
13{
14    /**
15     * サンプルを実行します。
16     *
17     * @return void
18     */
19    public function run(): void
20    {
21        // 再帰的な構造を持つ配列データ
22        $data = [
23            'Apple',
24            'Banana',
25            [
26                'Cherry',
27                'Durian',
28            ],
29            'Elderberry',
30        ];
31
32        // 配列を再帰的に走査するためのイテレータを作成します。
33        // RecursiveArrayIterator は巻き戻し可能です。
34        $arrayIterator = new RecursiveArrayIterator($data);
35        
36        // 再帰的なイテレータをフラットに(一次元的に)走査するためのイテレータを作成します。
37        $iterator = new RecursiveIteratorIterator($arrayIterator);
38
39        echo "1回目のループ:\n";
40        // foreach ループは、最初に内部で rewind() を呼び出し、イテレータを先頭に戻します。
41        foreach ($iterator as $key => $value) {
42            echo "{$key}: {$value}\n";
43        }
44
45        echo "\n2回目のループ:\n";
46        // イテレータが巻き戻し可能 (rewindable) なため、もう一度 foreach でループできます。
47        // このループの開始時にも、再度 rewind() が呼び出され、イテレータが先頭に戻ります。
48        // 注意: デフォルトのジェネレータは巻き戻し不可能 (not rewindable) なため、
49        // このような複数回の走査はできません。
50        foreach ($iterator as $key => $value) {
51            echo "{$key}: {$value}\n";
52        }
53    }
54}
55
56// サンプルコードの実行
57$example = new RewindableIteratorExample();
58$example->run();

RecursiveIteratorIterator::rewindは、イテレータを最初の要素に巻き戻すためのメソッドです。このメソッドは引数を取らず、戻り値もありません。開発者が直接呼び出すことは少なく、通常はforeachループのような言語構造によって内部的に呼び出されます。

サンプルコードは、foreachループが処理を開始する際に、内部でrewindメソッドを呼び出す様子を示しています。まず、多次元配列からRecursiveArrayIteratorを作成し、それをRecursiveIteratorIteratorでラップすることで、ネストされた配列をフラットに(一次元的に)走査する準備をします。

1回目のforeachループが始まると、PHPはイテレータのrewindメソッドを呼び出し、ポインタを先頭の要素にセットします。そして、すべての要素を順に処理します。サンプルコードでは、続けて2回目のforeachループを実行しています。このときも同様にrewindメソッドが呼び出されるため、イテレータは再び先頭に戻り、もう一度すべての要素を走査できます。

このように同じイテレータを複数回走査できるのは、RecursiveArrayIteratorが「巻き戻し可能(rewindable)」な性質を持つためです。一方で、PHPのジェネレータなどはデフォルトで巻き戻しができないため、2回目のループを実行しようとするとエラーになります。

foreachループは処理の開始時に、対象となるイテレータのrewind()メソッドを自動的に呼び出し、内部ポインタを先頭に戻します。このサンプルコードが2回ループできるのは、元データとなるRecursiveArrayIteratorがこの「巻き戻し」に対応しているためです。注意点として、全てのイテレータが巻き戻し可能ではありません。例えば、ジェネレータ関数(yieldを使用)などは、一度最後まで処理を進めると巻き戻すことができず、再度ループさせようとしても2回目は何も出力されません。使用するイテレータが巻き戻しに対応しているか意識することが、意図しない挙動を防ぐために重要です。

PHP RecursiveIteratorIterator::rewind() でイテレータをリセットする

1<?php
2
3declare(strict_types=1);
4
5/**
6 * RecursiveIteratorIterator::rewind() の使用例を示す関数
7 *
8 * この関数は、多次元配列を再帰的に処理するイテレータを作成し、
9 * 一度ループした後、rewind() メソッドでイテレータを先頭に戻し、
10 * 再度ループを実行することで、メソッドの効果を実証します。
11 */
12function demonstrateRewind(): void
13{
14    // サンプル用の多次元配列
15    $data = [
16        'fruit1' => 'apple',
17        'fruit2' => 'banana',
18        'other_fruits' => [
19            'orange',
20            'grape',
21        ],
22        'fruit3' => 'cherry',
23    ];
24
25    // 再帰的な配列からイテレータを作成
26    $arrayIterator = new RecursiveArrayIterator($data);
27    $iterator = new RecursiveIteratorIterator($arrayIterator);
28
29    // 1回目のループ: すべての要素を出力します
30    echo "1回目のループ:\n";
31    foreach ($iterator as $key => $value) {
32        echo "  {$key}: {$value}\n";
33    }
34    echo "\n";
35
36    // rewind() メソッドを呼び出して、イテレータを先頭に戻します。
37    // foreach ループは内部で自動的に rewind() を呼び出しますが、
38    // ここでは手動で呼び出すことで、一度終端に達したイテレータを
39    // 再利用できることを示します。
40    echo "iterator->rewind() を呼び出します...\n\n";
41    $iterator->rewind();
42
43    // 2回目のループ: rewind() によって再び先頭から要素を出力できます
44    echo "2回目のループ:\n";
45    foreach ($iterator as $key => $value) {
46        echo "  {$key}: {$value}\n";
47    }
48}
49
50// 関数を実行
51demonstrateRewind();

PHPのRecursiveIteratorIterator::rewind()メソッドは、イテレータを最初の要素の位置に巻き戻す機能を提供します。このメソッドは引数を取らず、戻り値もありません。

サンプルコードでは、まず多次元配列を順番に処理するためのイテレータ$iteratorを作成しています。1回目のforeachループでは、このイテレータを使って配列のすべての要素が最初から最後まで出力されます。このループが終了すると、イテレータはコレクションの終端に達した状態になります。

次に、$iterator->rewind()を明示的に呼び出しています。これにより、終端に達していたイテレータの内部ポインタが強制的に先頭に戻されます。その結果、2回目のforeachループを実行した際にも、再び配列の最初の要素から処理が開始され、1回目と全く同じ内容が出力できていることがわかります。

通常、foreachループは処理を開始する際に内部で自動的にrewind()を呼び出しますが、このサンプルのように手動で呼び出すことで、一度処理を終えたイテレータを再利用して、もう一度最初から処理を始めることが可能になります。

RecursiveIteratorIterator::rewind()メソッドは、イテレータを最初の要素に戻す機能を持っています。PHPのforeachループは、処理を開始する際に内部で自動的にrewind()を呼び出すため、通常は開発者が意識する必要はありません。このサンプルコードの重要な点は、一度foreachで最後まで処理したイテレータを、もう一度最初から使いたい場合にrewind()を手動で呼び出す必要があるということです。もしrewind()を呼び出さずに2回目のループを実行しようとすると、イテレータはすでに終端に達しているため、ループは何も実行せずに終了します。このように、一度使い終わったイテレータオブジェクトを再利用する際にrewind()は不可欠なメソッドです。

関連コンテンツ