【PHP8.x】DirectoryIterator::rewind()メソッドの使い方
rewindメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
rewindメソッドは、DirectoryIteratorクラスのオブジェクトが保持する内部ポインタを、ディレクトリ内の最初の要素の位置にリセットするメソッドです。
DirectoryIteratorは、指定されたディレクトリの内容(ファイルやサブディレクトリ)を順番に処理するための仕組みを提供します。この処理を行う際、イテレータは現在どの要素を指しているかを示す内部ポインタを持っています。例えば、ディレクトリ内のファイルやフォルダを一つずつ確認していく際に、その確認の「現在地」を示すのが内部ポインタです。
一度ディレクトリ内の要素を順に処理し終えた後や、途中で処理を中断して、もう一度最初からディレクトリの要素を処理し直したい場合に、このrewindメソッドが非常に役立ちます。rewindメソッドを呼び出すことで、この内部ポインタは必ず最初の要素を指す状態に戻ります。
PHPのforeachループでDirectoryIteratorオブジェクトを使用する場合、foreachループが始まる際に自動的にrewindメソッドが呼び出されるため、通常は開発者が明示的にrewindを呼び出す必要はありません。しかし、foreachループを使わずに、手動でnext()メソッドなどを用いてイテレータを操作し、特定の位置から処理を始めたり、途中でポインタを先頭に戻したりしたい場合に、rewindメソッドを手動で呼び出すことになります。これにより、イテレータを柔軟に制御し、効率的なファイルシステム操作を実現できます。
構文(syntax)
1<?php 2 3$iterator = new DirectoryIterator('.'); 4$iterator->rewind();
引数(parameters)
引数なし
引数はありません
戻り値(return)
戻り値なし
戻り値はありません
サンプルコード
DirectoryIterator::rewind()で複数回走査する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * DirectoryIterator::rewind() メソッドの使用例をデモンストレーションします。 7 * 8 * この関数は、一時ディレクトリを作成し、その中のファイルを DirectoryIterator で2度走査します。 9 * 1度目の走査後、rewind() メソッドを呼び出すことで、イテレータを先頭に戻し、 10 * 再度走査できることを示します。 11 * DirectoryIterator は、巻き戻し可能なイテレータ(Rewindable Iterator)の一例です。 12 */ 13function demonstrateDirectoryIteratorRewind(): void 14{ 15 // デモンストレーションのための一時ディレクトリとファイルを作成 16 $tempDir = __DIR__ . DIRECTORY_SEPARATOR . 'temp_test_dir_' . uniqid('dir_', true); 17 if (!mkdir($tempDir) && !is_dir($tempDir)) { 18 throw new \RuntimeException(sprintf('Directory "%s" was not created', $tempDir)); 19 } 20 file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'file1.txt', 'Content for file1'); 21 file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'file2.txt', 'Content for file2'); 22 file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'another_file.log', 'Log content'); 23 24 echo "--- 1回目のイテレーション ---\n"; 25 26 try { 27 // DirectoryIterator のインスタンスを作成 28 // DirectoryIterator は PHP の SplFileInfo を継承したクラスで、 29 // ディレクトリの内容をイテレートするためのものです。 30 $iterator = new DirectoryIterator($tempDir); 31 32 // 1回目の走査 33 foreach ($iterator as $fileInfo) { 34 // '.' と '..' はスキップして表示を簡潔に 35 if ($fileInfo->isDot()) { 36 continue; 37 } 38 echo "ファイル: " . $fileInfo->getFilename() . "\n"; 39 } 40 41 echo "\n--- イテレータを巻き戻し (rewind()) ---\n"; 42 // rewind() メソッドは、イテレータの内部ポインタを先頭にリセットします。 43 // これにより、同じ要素セットを再度最初から走査することが可能になります。 44 // DirectoryIterator は「巻き戻し可能なイテレータ」の一例です。 45 // 一方、PHPの標準的なジェネレータ(`yield` を使用して作成されるもの)は、 46 // 通常は巻き戻し可能ではないため、イテレーション開始後に rewind() を呼び出すとエラーになります。 47 $iterator->rewind(); 48 49 echo "\n--- rewind() 後の2回目のイテレーション ---\n"; 50 51 // rewind() 後の2回目の走査 52 foreach ($iterator as $fileInfo) { 53 // '.' と '..' はスキップして表示を簡潔に 54 if ($fileInfo->isDot()) { 55 continue; 56 } 57 echo "ファイル: " . $fileInfo->getFilename() . "\n"; 58 } 59 60 } finally { 61 // デモンストレーション後に一時ディレクトリとファイルをクリーンアップ 62 $items = array_diff(scandir($tempDir), ['.', '..']); 63 foreach ($items as $item) { 64 $path = $tempDir . DIRECTORY_SEPARATOR . $item; 65 // この例ではサブディレクトリを作成していないため、ファイルの削除のみ 66 if (is_file($path)) { 67 unlink($path); 68 } 69 } 70 rmdir($tempDir); 71 echo "\n一時ディレクトリとファイルをクリーンアップしました。\n"; 72 } 73} 74 75// デモンストレーション関数を実行 76demonstrateDirectoryIteratorRewind();
PHP 8で利用できるDirectoryIteratorクラスは、ファイルシステム上のディレクトリの内容を一つずつ順に処理(イテレート)するための機能を提供します。このDirectoryIteratorクラスに実装されているrewind()メソッドは、イテレータの内部ポインタを最初の要素(ディレクトリの先頭)にリセットする役割を持ちます。これにより、一度ディレクトリ内のすべての項目を処理し終えた後でも、再度最初から同じ項目を繰り返し走査することが可能になります。
rewind()メソッドは引数を受け取らず、戻り値もありません。その目的は、イテレータを初期状態に戻すことのみです。このような機能を持つイテレータは「巻き戻し可能なイテレータ」(Rewindable Iterator)と呼ばれ、DirectoryIteratorはその代表的な例の一つです。
特に、データセットを複数回にわたって異なる方法で処理する必要がある場合に、rewind()は非常に有効です。注意点として、PHPの標準的なジェネレータ(yieldキーワードで作成されるもの)は、通常は巻き戻し可能ではありません。一度要素を生成し終えると再利用できないため、rewind()を呼び出すとエラーが発生します。
このサンプルコードは、DirectoryIteratorが巻き戻し可能であることを明確に示しています。一時ディレクトリの内容を一度表示した後、rewind()を呼び出してイテレータを先頭に戻し、再度同じ内容を最初から表示することで、rewind()の動作を具体的に理解することができます。この機能により、柔軟なファイルシステム操作が可能となります。
DirectoryIterator::rewind()メソッドは、ディレクトリの内容を走査するイテレータの内部ポインタを先頭に戻し、同じ内容を最初から再度読み込めるようにします。これは、DirectoryIteratorが「巻き戻し可能なイテレータ」であるため可能で、引数や戻り値はありません。重要な注意点として、PHPの標準的なジェネレータ(yieldキーワードで作成するもの)は、通常は巻き戻し可能ではありません。そのため、ジェネレータに対してrewind()を呼び出すと実行時エラーになる点に特に注意が必要です。イテレータの種類を理解し、このメソッドを適切に活用してください。