W3docs

rewinddir()

Узнайте, как rewinddir() в PHP сбрасывает внутренний указатель потока каталога в начало для повторного чтения без переоткрытия дескриптора.

При чтении каталога в PHP внутренний указатель отслеживает, насколько далеко вы продвинулись. Достигнув конца, указатель остаётся там — повторный вызов readdir() вернёт false без каких-либо записей. rewinddir() перемещает указатель обратно к первой записи, позволяя прочитать каталог во второй раз без его повторного открытия. На этой странице описано, что делает функция, её синтаксис, рабочий пример с несколькими проходами, типичные ловушки и случаи, когда стоит (и не стоит) её использовать.

Синтаксис

rewinddir(?resource $dir_handle = null): void
  • $dir_handle — дескриптор каталога, ранее возвращённый функцией opendir(). Если параметр опущен, PHP использует дескриптор последнего вызова opendir().
  • Возвращаемое значениеrewinddir() возвращает void (в более старых версиях PHP — null). Функция не сигнализирует об успехе или ошибке; при передаче недействительного дескриптора PHP генерирует TypeError или предупреждение.

Функция почти всегда используется совместно с opendir(), readdir() и closedir().

Как работает rewinddir()

Дескриптор каталога ведёт себя как курсор по записям каталога. readdir() продвигает этот курсор на одну запись за вызов и возвращает false, когда записи заканчиваются. rewinddir() просто перемещает курсор в начало, так что следующий вызов readdir() начнёт с первой записи.

Двойное чтение каталога

Это основной сценарий использования: перебрать каталог, а затем пройти по нему снова с того же дескриптора. Обратите внимание, что readdir($h) не возвращает записей при втором проходе до тех пор, пока не будет вызван rewinddir().

<?php
$h = opendir(__DIR__);
if ($h === false) {
    die("Failed to open directory\n");
}

echo "First pass:\n";
while (($file = readdir($h)) !== false) {
    echo "  $file\n";
}

// Without rewinddir(), this loop would print nothing.
rewinddir($h);

echo "Second pass:\n";
while (($file = readdir($h)) !== false) {
    echo "  $file\n";
}

closedir($h);
?>

Оба прохода выводят одинаковый набор записей (включая псевдо-директории . и .., которые readdir() всегда возвращает).

Распространённая ловушка: строгая проверка на false

Всегда сравнивайте результат readdir() с !== false, а не просто != или с помощью проверки на истинность. Каталог может законно содержать запись с именем "0", которое в PHP является ложным — при нестрогой проверке цикл завершится раньше времени, молча пропустив файлы.

<?php
// Wrong: stops as soon as it hits a file named "0" (or an empty name)
while ($file = readdir($h)) { /* ... */ }

// Correct: only stops at the genuine end of the stream
while (($file = readdir($h)) !== false) { /* ... */ }
?>

Когда использовать rewinddir() — и когда не стоит

Используйте rewinddir(), когда вам нужен более одного прохода по одному и тому же открытому дескриптору, например, чтобы подсчитать итог на первом проходе (количество файлов, суммарный размер) и обработать каждую запись на втором. Это дешевле, чем вызывать closedir() и снова opendir(), поскольку позволяет избежать повторного открытия базового файлового дескриптора.

Если вам нужны записи только один раз или в отсортированном виде, предпочтите scandir(), который возвращает весь список в виде массива за один вызов — без необходимости управлять указателем. Обзор всех функций для работы с каталогами см. в главе PHP Directory.

Заключение

rewinddir() сбрасывает внутренний указатель потока каталога в начало, позволяя повторно прочитать каталог без лишних затрат на закрытие и повторное открытие дескриптора. В паре с opendir(), readdir() и closedir() она делает многопроходный обход каталога простым и эффективным. Используйте scandir() вместо неё, когда достаточно одного отсортированного списка.

graph TD
    A[opendir] --> B[readdir]
    B --> C{More items?}
    C -->|Yes| B
    C -->|No| D[rewinddir]
    D --> B
    B --> E[closedir]

Практика

Практика
Какова основная функция 'rewinddir()' в PHP?
Какова основная функция 'rewinddir()' в PHP?
Was this page helpful?