W3docs

rewind()

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

Введение

Когда вы читаете файл в PHP, внутренний указатель файла отслеживает вашу текущую позицию. Каждое чтение перемещает указатель вперёд, поэтому после достижения конца файла дальнейшие операции чтения не возвращают ничего. Функция rewind() перемещает указатель обратно к байту 0 — самому началу — позволяя вам читать тот же файл снова без его закрытия и повторного открытия.

На этой странице объясняется, что делает rewind(), её синтаксис и возвращаемое значение, когда её использовать, типичные ошибки и запускаемые примеры, которые вы можете адаптировать.

Что такое указатель файла

Представьте указатель файла как курсор внутри открытого файла. Такие функции, как fread(), fgets() и fgetcsv(), читают с позиции курсора, а затем перемещают его вперёд на количество прочитанных байтов. Вы можете проверить текущую позицию курсора с помощью ftell() и переместить его в произвольную позицию с помощью fseek().

rewind($handle) — это удобное сокращение для «вернуться в начало»; оно эквивалентно fseek($handle, 0).

Синтаксис

rewind(resource $handle): bool
  • $handle — ресурс-указатель на файл, который ещё открыт; как правило, возвращается функцией fopen(). Он должен указывать на поток, допускающий позиционирование.
  • Возвращает true в случае успеха и false в случае ошибки.

Когда и зачем использовать

Используйте rewind() всякий раз, когда нужно прочитать или обработать один и тот же открытый файл более одного раза за время выполнения скрипта:

  • Подсчёт, затем обработка. Первый проход для подсчёта строк или валидации, второй — для выполнения основной работы.
  • Чтение после записи. После записи в файл, открытый в режиме чтения/записи ('w+', 'r+', 'a+'), перемотайте перед тем, как читать записанное.
  • Потоки в памяти. Когда вы формируете содержимое в потоке php://memory или php://temp, перемотайте перед его чтением.

Если вы читаете файл только один раз, rewind() вам не нужна.

Примеры

Пример 1: Чтение одного файла дважды

В этом примере создаётся временный файл, который читается до конца, затем перематывается и читается снова.

<?php

// Create a temporary file we can read and write.
$handle = tmpfile();
fwrite($handle, "line one\nline two\n");

// Move to the start so we can read what we just wrote.
rewind($handle);

echo "First read:\n";
echo fread($handle, 1024);

// The pointer is now at the end; reading again gives nothing.
echo "After first read, position: " . ftell($handle) . "\n";

// Rewind and read the whole file again.
rewind($handle);
echo "Second read:\n";
echo fread($handle, 1024);

fclose($handle);

Результат:

First read:
line one
line two
After first read, position: 18
Second read:
line one
line two

Первый вызов fread() оставляет указатель на байте 18 (конец файла). Без rewind() второе чтение вернуло бы пустую строку. После перемотки указатель возвращается на 0, и полное содержимое становится доступным снова.

Пример 2: Запись, перемотка и последующее чтение

Когда поток открыт и для записи, и для чтения, rewind() позволяет проверить записанное.

<?php

// php://memory is an in-memory read/write stream.
$handle = fopen('php://memory', 'r+');

fwrite($handle, 'Hello, W3Docs!');

// Without rewind, the pointer sits after the written text,
// so reading now would return an empty string.
rewind($handle);

$content = stream_get_contents($handle);
echo $content; // Hello, W3Docs!

fclose($handle);

Результат:

Hello, W3Docs!

Пример 3: Всегда проверяйте возвращаемое значение

rewind() возвращает false, если поток не поддерживает позиционирование (например, несекьюрный сетевой поток или канал).

<?php

$handle = fopen('php://memory', 'r+');
fwrite($handle, 'data');

if (rewind($handle)) {
    echo "Pointer reset. Position: " . ftell($handle) . "\n";
} else {
    echo "This stream cannot be rewound.\n";
}

fclose($handle);

Результат:

Pointer reset. Position: 0

Типичные ошибки

  • Указатель уже находится в конце после чтения. Именно для этого и существует rewind(). Если второе чтение не возвращает ничего, скорее всего, вы забыли перемотать.
  • Режим добавления ('a' / 'a+'). Перемотка перемещает указатель чтения в начало, но в режиме добавления каждый вызов fwrite() всё равно записывает в конец файла, независимо от позиции указателя.
  • Непозиционируемые потоки. Каналы, сокеты и некоторые HTTP-потоки нельзя перемотать; rewind() вернёт false. Проверяйте возвращаемое значение, если источник может не поддерживать позиционирование.
  • Закрытые дескрипторы. Вызов rewind() для дескриптора, уже переданного в fclose(), вызовет предупреждение. Перематывайте до закрытия.

Связанные функции

  • fseek() — перемещает указатель на любое смещение в байтах (rewind() эквивалентна fseek($handle, 0)).
  • ftell() — возвращает текущую позицию указателя.
  • fopen() — открывает файл или поток и возвращает дескриптор.
  • fread() / fgets() — читают с текущей позиции.
  • fclose() — закрывает дескриптор по завершении работы.

Заключение

rewind() сбрасывает внутренний указатель открытого файла в начало, позволяя повторно читать или обрабатывать данные в рамках одного запуска скрипта. Это тонкая удобная обёртка вокруг fseek($handle, 0). Не забывайте проверять возвращаемое значение для непозиционируемых потоков, учитывайте поведение режима добавления и перематывайте до закрытия дескриптора.

Практика

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