【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()を呼び出すと実行時エラーになる点に特に注意が必要です。イテレータの種類を理解し、このメソッドを適切に活用してください。
DirectoryIterator::rewind()で先頭に戻す
1<?php 2 3/** 4 * 指定された DirectoryIterator のエントリを順に表示します。 5 * 6 * @param DirectoryIterator $iterator DirectoryIterator のインスタンス 7 * @param string $label 表示の目的を説明するラベル 8 */ 9function displayDirectoryEntries(DirectoryIterator $iterator, string $label): void 10{ 11 echo "--- " . $label . " ---\n"; 12 $count = 0; 13 foreach ($iterator as $fileinfo) { 14 // "." (カレントディレクトリ) と ".." (親ディレクトリ) は通常スキップします。 15 if ($fileinfo->isDot()) { 16 continue; 17 } 18 echo " " . $fileinfo->getFilename() . "\n"; 19 $count++; 20 } 21 if ($count === 0) { 22 echo " (このディレクトリにはエントリがありません)\n"; 23 } 24 echo "\n"; 25} 26 27try { 28 // 現在のスクリプトがあるディレクトリ (カレントディレクトリ) を対象とする 29 // DirectoryIterator のインスタンスを作成します。 30 $iterator = new DirectoryIterator(__DIR__); 31 32 // 最初にディレクトリのエントリをイテレート(順に処理)して表示します。 33 // この時点でイテレータの内部ポインタは末尾に移動しています。 34 displayDirectoryEntries($iterator, "最初のイテレーション"); 35 36 // rewind() メソッドを呼び出し、イテレータの内部ポインタを先頭に戻します。 37 // これにより、もう一度最初からエントリを読み込むことができるようになります。 38 echo "DirectoryIterator::rewind() を呼び出し、イテレータを先頭に戻します。\n\n"; 39 $iterator->rewind(); 40 41 // rewind() 後、再度ディレクトリのエントリをイテレートして表示します。 42 // 最初のイテレーションと同じ結果が表示されることを確認できます。 43 displayDirectoryEntries($iterator, "rewind() 後のイテレーション"); 44 45} catch (UnexpectedValueException $e) { 46 // ディレクトリが存在しないなど、エラーが発生した場合の処理 47 echo "エラー: " . $e->getMessage() . "\n"; 48} 49 50?>
DirectoryIteratorクラスは、指定されたディレクトリ内のファイルやサブディレクトリを順番に処理(イテレート)するためのPHPの機能です。本サンプルコードでは、このDirectoryIteratorクラスが提供するrewind()メソッドの働きを具体的に示しています。
rewind()メソッドは、引数を必要とせず、特別な戻り値もありません。その主な役割は、DirectoryIteratorの内部的な処理位置(ポインタ)を、ディレクトリの先頭に戻すことです。これにより、一度最後まで読み進めたイテレータを、再度最初から利用できるようになります。
サンプルコードでは、まず現在のディレクトリを対象にDirectoryIteratorのインスタンスを作成します。次に、displayDirectoryEntries関数を使って、ディレクトリ内のエントリを一度すべて表示します。この処理が完了すると、イテレータの内部ポインタは末尾に移動しており、この状態では再度最初からエントリを読み込むことはできません。
ここで$iterator->rewind();を呼び出します。このメソッドの実行により、イテレータの内部ポインタがリセットされ、ディレクトリの先頭に戻ります。その結果、再度displayDirectoryEntries関数を呼び出すことで、最初のイテレーション時とまったく同じディレクトリ内容が再び表示されることを確認できます。これは、rewind()メソッドがイテレータを再利用可能にするために不可欠な機能であることを示しています。
DirectoryIterator::rewind()は、一度最後まで読み込んだイテレータの読み込み位置を先頭に戻すメソッドです。通常のPHP配列はforeachなどで何回でも最初から処理できますが、DirectoryIteratorのようなイテレータは一度最後まで到達すると、その位置で停止します。そのため、同じイテレータを使って再度最初からファイルやディレクトリを処理したい場合は、このrewind()を呼び出す必要があります。これにより、サンプルコードのように同じ内容を複数回表示できます。このメソッドは配列にはなく、イテレータ特有の機能ですので混同しないよう注意が必要です。イテレータを再利用する際に利用しますが、毎回必ず呼び出す必要はありません。