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

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

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

作成日: 更新日:

基本的な使い方

seekメソッドは、GlobIteratorオブジェクト内でイテレータの現在のポインタを指定された位置に移動させるメソッドです。GlobIteratorは、ファイルシステムのパスパターンに合致するファイルやディレクトリを順次処理するためのイテレータです。このseekメソッドを利用することで、イテレータが現在指し示している要素の位置を、任意の0から始まるインデックスであるpositionへ直接変更することができます。

引数として整数値のpositionを受け取ります。これは移動先のイテレータ要素のインデックスを示します。メソッドが正常に実行されると、イテレータの内部ポインタは指定されたpositionに移動します。以降のイテレータ操作(例えば、current()next()など)は、この新しい位置から開始されます。もし指定されたpositionが、GlobIteratorが保持する要素の範囲外である場合、OutOfBoundsExceptionがスローされますので、プログラミング時にはこの例外を適切に処理する必要があります。

このメソッドは、特定の条件を満たすファイルに直接アクセスしたい場合や、イテレータの先頭からではなく途中から処理を再開したい場合などに有用です。例えば、大量のファイルの中から特定の順番にあるファイルだけを読み込みたい際などに、柔軟な制御を可能にします。このメソッドは値を返しません(void)。

構文(syntax)

1<?php
2// 現在のディレクトリにあるすべてのPHPファイルに対してイテレータを作成します。
3// 実際の実行時には、対象となるファイルが一つ以上存在する必要があります。
4$iterator = new GlobIterator(__DIR__ . '/*.php');
5
6// イテレータのカーソルを、指定された位置(この例ではインデックス1)に移動させます。
7// インデックスは0から始まります。
8$iterator->seek(1);

引数(parameters)

int $offset

  • int $offset: 移動する位置を示す整数

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

PHP GlobIterator::seek() で特定位置に移動する

1<?php
2
3/**
4 * GlobIterator::seek() メソッドの使用例を示します。
5 * このメソッドは、イテレータを指定されたオフセット(位置)に移動させるために使用されます。
6 * GlobIterator は SeekableIterator インターフェースを実装しているため、この操作が可能です。
7 */
8function demonstrateGlobIteratorSeek(): void
9{
10    // デモンストレーション用に一時ディレクトリとファイルを準備します。
11    // sys_get_temp_dir() を使用してOSの一時ディレクトリ内に安全な場所を作成します。
12    $tempDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'glob_seek_example_' . uniqid();
13    if (!mkdir($tempDir, 0777, true)) {
14        echo "エラー: 一時ディレクトリの作成に失敗しました。\n";
15        return;
16    }
17
18    // いくつかのテストファイルを作成します。GlobIteratorはファイル名をアルファベット順に処理します。
19    $filesToCreate = ['apple.txt', 'banana.txt', 'cherry.txt', 'date.txt'];
20    foreach ($filesToCreate as $fileName) {
21        file_put_contents($tempDir . DIRECTORY_SEPARATOR . $fileName, "これは {$fileName} の内容です。");
22    }
23
24    echo "一時ディレクトリにテストファイルを作成しました: $tempDir\n\n";
25
26    // GlobIterator をインスタンス化し、作成したファイル群を対象とします。
27    $iterator = new GlobIterator($tempDir . DIRECTORY_SEPARATOR . '*.txt');
28
29    echo "GlobIterator が検出したファイルの総数: " . $iterator->count() . " 個\n\n";
30
31    // イテレータの初期位置(最初のファイル)を確認します。
32    if ($iterator->valid()) {
33        echo "現在のファイル (初期位置): " . basename($iterator->current()) . "\n";
34    }
35
36    // seek() メソッドを使用して、イテレータを特定のオフセットに移動させます。
37    // オフセットは0から始まります。
38    $offset = 2; // 3番目のファイル (インデックス2) に移動します。
39    echo "\nオフセット $offset (3番目のファイル) に移動します...\n";
40    try {
41        $iterator->seek($offset);
42        if ($iterator->valid()) {
43            echo "新しい現在のファイル: " . basename($iterator->current()) . "\n";
44        } else {
45            echo "エラー: オフセット $offset は範囲外か、イテレータが無効です。\n";
46        }
47    } catch (OutOfBoundsException $e) {
48        echo "エラー: 指定されたオフセット $offset は範囲外です。 (" . $e->getMessage() . ")\n";
49    }
50
51    // 別のオフセットに移動してみます。
52    $offset = 0; // 最初のファイル (インデックス0) に戻ります。
53    echo "\nオフセット $offset (1番目のファイル) に移動します...\n";
54    try {
55        $iterator->seek($offset);
56        if ($iterator->valid()) {
57            echo "新しい現在のファイル: " . basename($iterator->current()) . "\n";
58        } else {
59            echo "エラー: オフセット $offset は範囲外か、イテレータが無効です。\n";
60        }
61    } catch (OutOfBoundsException $e) {
62        echo "エラー: 指定されたオフセット $offset は範囲外です。 (" . $e->getMessage() . ")\n";
63    }
64
65    // 作成した一時ファイルとディレクトリをクリーンアップします。
66    foreach ($filesToCreate as $fileName) {
67        unlink($tempDir . DIRECTORY_SEPARATOR . $fileName);
68    }
69    rmdir($tempDir);
70    echo "\n一時ファイルとディレクトリをクリーンアップしました: $tempDir\n";
71}
72
73// デモンストレーション関数を実行します。
74demonstrateGlobIteratorSeek();

PHPのGlobIterator::seek()メソッドは、ファイルやディレクトリのリストを扱うGlobIteratorオブジェクトにおいて、現在参照している位置を指定したオフセット(位置)に移動させるために使用されます。この機能は、GlobIteratorSeekableIteratorインターフェースを実装しているため利用可能です。

seek()メソッドは、int $offsetという整数を引数として受け取ります。この$offsetは、0から始まるインデックス(位置)を示し、イテレータをそのインデックスの要素へ移動させます。このメソッドに特定の戻り値はありません。

サンプルコードでは、まず一時ディレクトリ内に複数のテキストファイルを作成し、これらのファイルをGlobIteratorで走査対象としています。イテレータが初期化された後、seek(2)を呼び出すことで、リストの3番目のファイル(インデックス2)へイテレータを移動させ、そのファイル名を表示しています。さらに、seek(0)を呼び出すことで、リストの最初のファイル(インデックス0)へ再度移動し、そのファイル名を表示しています。このようにseek()を使うことで、ファイルリストのようなデータ構造内を、ループで順に処理するだけでなく、任意の場所へ直接ジャンプして処理を再開できるのが特徴です。指定されたオフセットが有効な範囲外の場合には、OutOfBoundsExceptionが発生します。処理の最後には、作成した一時ファイルとディレクトリを適切に削除し、環境をクリーンアップしています。

GlobIterator::seek()は、イテレータの現在位置を指定したオフセットに移動させるメソッドです。オフセットは0から始まり、最初の要素が0となります。存在しないオフセットを指定するとOutOfBoundsExceptionが発生するため、try-catchブロックで適切にエラーを処理することが重要です。このメソッド自体は戻り値を返さないため、移動後の要素はcurrent()メソッドで確認してください。GlobIteratorSeekableIteratorインターフェースを実装しているため、このseek操作が可能です。サンプルコードのように一時ファイルを扱う際は、作成したファイルを確実にクリーンアップし、本番環境でのパス指定には特に注意が必要です。

GlobIterator::seek で特定位置のファイルへ移動する

1<?php
2
3/**
4 * GlobIterator の seek() メソッドの使用例を示します。
5 * 指定されたオフセット(位置)にイテレータのポインタを移動させ、
6 * その位置の要素にアクセスする方法を学びます。
7 *
8 * このスクリプトは一時的なファイルを作成し、その後削除します。
9 */
10function demonstrateGlobIteratorSeek(): void
11{
12    // 一時的なテストファイルを作成するディレクトリを定義
13    $tempDir = __DIR__ . '/glob_seek_test_temp';
14    if (!is_dir($tempDir)) {
15        mkdir($tempDir, 0777, true); // ディレクトリが存在しない場合は作成
16        echo "一時ディレクトリを作成しました: " . $tempDir . "\n";
17    }
18
19    // テスト用のファイルをいくつか作成
20    $fileNames = [];
21    $numFiles = 3;
22    for ($i = 0; $i < $numFiles; $i++) {
23        $fileName = $tempDir . '/test_file_' . $i . '.txt';
24        file_put_contents($fileName, "これはテストファイル {$i} の内容です。");
25        $fileNames[] = $fileName;
26    }
27
28    echo "作成したテストファイル:\n";
29    foreach ($fileNames as $name) {
30        echo "- " . basename($name) . "\n";
31    }
32    echo "\n";
33
34    try {
35        // GlobIterator を作成し、特定のパターンにマッチするファイルを検索
36        // パス区切り文字はシステム依存のため、WindowsでもUnixでも動作するようにしています。
37        $iterator = new GlobIterator($tempDir . DIRECTORY_SEPARATOR . 'test_file_*.txt');
38
39        echo "GlobIterator で見つかったファイル数: " . $iterator->count() . "\n\n";
40
41        if ($iterator->count() > 0) {
42            // seek() メソッドを使ってイテレータのポインタを指定されたオフセット(位置)に移動させる
43
44            // オフセット 1 (2番目の要素) に移動し、そのファイル名を表示
45            $offsetToSeek = 1;
46            if ($offsetToSeek < $iterator->count()) {
47                $iterator->seek($offsetToSeek);
48                echo "--- seek({$offsetToSeek}) 後 --- \n";
49                // current() で現在の要素(ファイルパス)を取得
50                echo "現在のファイル: " . basename($iterator->current()) . "\n";
51                // key() で現在のキー(オフセット)を取得
52                echo "現在のキー (オフセット): " . $iterator->key() . "\n\n";
53            } else {
54                echo "オフセット {$offsetToSeek} はファイルの範囲外です。\n\n";
55            }
56
57
58            // オフセット 0 (最初の要素) に移動し、そのファイル名を表示
59            $offsetToSeek = 0;
60            if ($offsetToSeek < $iterator->count()) {
61                $iterator->seek($offsetToSeek);
62                echo "--- seek({$offsetToSeek}) 後 --- \n";
63                echo "現在のファイル: " . basename($iterator->current()) . "\n";
64                echo "現在のキー (オフセット): " . $iterator->key() . "\n\n";
65            } else {
66                echo "オフセット {$offsetToSeek} はファイルの範囲外です。\n\n";
67            }
68
69            // 範囲外のオフセットを試す場合
70            // seek() は例外を投げませんが、イテレータは有効な位置になくなります。
71            $offsetToSeek = $iterator->count(); // 存在しないインデックス
72            echo "--- seek({$offsetToSeek}) 後 (範囲外のオフセット) --- \n";
73            $iterator->seek($offsetToSeek);
74            if ($iterator->valid()) { // valid() でイテレータが有効な位置にあるか確認
75                echo "現在のファイル: " . basename($iterator->current()) . "\n";
76                echo "現在のキー (オフセット): " . $iterator->key() . "\n\n";
77            } else {
78                echo "イテレータは有効な位置にありません。指定したオフセット {$offsetToSeek} は範囲外か、イテレータの終端です。\n\n";
79            }
80
81        } else {
82            echo "指定されたパターンにマッチするファイルが見つかりませんでした。\n";
83        }
84
85    } catch (Exception $e) {
86        echo "エラーが発生しました: " . $e->getMessage() . "\n";
87    } finally {
88        // 後処理: 作成したテストファイルを削除
89        echo "--- 後処理: 作成したファイルとディレクトリを削除します ---\n";
90        foreach ($fileNames as $fileName) {
91            if (file_exists($fileName)) {
92                unlink($fileName);
93                echo "削除: " . basename($fileName) . "\n";
94            }
95        }
96        // 作成したディレクトリも削除 (ディレクトリが空の場合のみ)
97        // . と .. を考慮してファイル数をチェック
98        if (is_dir($tempDir) && count(scandir($tempDir)) == 2) {
99            rmdir($tempDir);
100            echo "削除: " . basename($tempDir) . "\n";
101        } else if (is_dir($tempDir)) {
102            echo "ディレクトリ '" . basename($tempDir) . "' にまだファイルが残っているため削除できませんでした。\n";
103        }
104    }
105}
106
107// 関数を実行
108demonstrateGlobIteratorSeek();
109
110?>

PHPのGlobIterator::seek()メソッドは、ファイルシステム上の特定のパターンに一致するファイルやディレクトリのリストを扱うGlobIteratorオブジェクトにおいて、内部のポインタを指定した数値のオフセット(位置)に直接移動させるために使用します。これにより、配列のインデックスのように0から始まる数値で指定した位置の要素に直接アクセスできるようになります。

引数int $offsetには、ポインタを移動させたい対象の要素のオフセット(位置)を数値で指定します。例えばseek(0)は最初の要素へ、seek(1)は2番目の要素へポインタを移動させます。このメソッドはポインタを移動させるだけであり、特に値を返しません。

seek()メソッドでポインタを移動させた後、current()メソッドを使ってその位置の要素(ファイルパス)を取得し、key()メソッドで現在のオフセットを確認できます。もし指定したオフセットがGlobIteratorの要素数の範囲外であった場合、イテレータは有効な位置に移動せず、valid()メソッドでその状態を確認することができます。この機能は、ファイルリストの中から特定の条件を満たす要素へ素早くアクセスしたい場合に役立ちます。

GlobIterator::seek()は、イテレータの現在位置を、指定番号(オフセット)へ直接移動させるメソッドです。オフセットは0から始まります。

このメソッドは位置を移動するだけで要素は返しません。移動後のファイル名などを取得するにはcurrent()メソッドを、現在のオフセットを取得するにはkey()メソッドを使います。

特に、指定オフセットがイテレータの要素数を超える場合、seek()はエラーを出さずイテレータが有効な位置ではなくなるため、valid()で必ず確認し、その後にcurrent()などを利用して安全に利用しましょう。ファイル操作を伴うため、一時ファイルの削除といった後処理も重要です。

関連コンテンツ