rewind()
Узнайте, как PHP-функция rewind() сбрасывает указатель файла в начало для повторного чтения. Синтаксис, возвращаемое значение, примеры и сравнение с fseek().
Введение
Когда вы открываете файл в PHP, система отслеживает указатель файла — внутреннюю позицию, которая обозначает место следующей операции чтения или записи. Каждый раз, когда вы читаете с помощью fgets() или fread(), указатель перемещается вперёд. Функция rewind() возвращает указатель в самое начало файла (байт 0), чтобы вы могли снова читать его с начала без закрытия и повторного открытия.
В этой главе объясняется, что делает rewind(), её синтаксис и возвращаемое значение, а также когда стоит использовать её вместо fseek().
Синтаксис
rewind(resource $stream): bool$stream— указатель файла, возвращённый функциейfopen()(или аналогичным потоковым ресурсом). Поток должен быть действительным и допускать позиционирование.- Возвращает
trueпри успехе иfalseпри ошибке.
Вызов rewind($stream) эквивалентен fseek($stream, 0): оба перемещают указатель в начало файла. Используйте ftell() в любой момент, чтобы узнать текущую позицию указателя.
Примечание: В потоках, открытых в режиме добавления (
'a'или'a+'), указатель чтения перемещается в начало, однако записи по-прежнему добавляются в конец файла.
Пример: повторное чтение файла с начала
После прочтения части файла rewind() позволяет начать сначала:
<?php
$handle = fopen('notes.txt', 'r');
// Read the first line — this advances the pointer
echo fgets($handle); // e.g. "First line"
echo 'Pointer is at: ' . ftell($handle); // a non-zero byte offset
// Send the pointer back to the beginning
rewind($handle);
echo 'After rewind: ' . ftell($handle); // 0
// Re-read the same first line
echo fgets($handle); // "First line" again
fclose($handle);Первый вызов fgets() читает строку и оставляет указатель где-то в середине файла, поэтому ftell() возвращает ненулевое смещение. После rewind() функция ftell() возвращает 0, и следующая операция чтения снова начинается с первого байта.
Когда использовать rewind()
- Два прохода по одному файлу. Например, сначала подсчитайте строки в файле, затем обработайте их в цикле — без повторного открытия файла.
- Сброс после записи. Вы записываете во временный поток, затем вызываете
rewind()и читаете то, что только что записали. - Повторное чтение потока, к которому есть только дескриптор, например
php://memoryилиphp://temp.
Используйте fseek(), если нужно перейти к произвольному смещению, а не в самое начало. Для дескрипторов директорий эквивалентом сброса является rewinddir().
Распространённые ошибки
- Непозиционируемые потоки. Некоторые потоки (сетевые сокеты, отдельные каналы) не поддерживают перемотку;
rewind()вернётfalse. Всегда проверяйте возвращаемое значение, если поток может не поддерживать позиционирование. - Путаница между указателями чтения и записи в режиме добавления. В режиме
'a'/'a+'перемотка не позволяет перезаписать данные с начала — новые данные по-прежнему добавляются в конец. - Забывают, что чтение снова перемещает указатель.
rewind()только сбрасывает позицию; следующий вызовfgets()/fread()снова переместит её вперёд.
Заключение
rewind() сбрасывает указатель файла в начало, чтобы можно было читать его заново с самого начала. Функция возвращает true при успехе и false при ошибке, и ведёт себя как fseek($stream, 0). Она хорошо сочетается с fopen(), fgets(), ftell() и fseek(), когда нужно выполнить несколько проходов по одному файлу или потоку.