feof()
Функция feof() в PHP проверяет, достигнут ли конец файла. Незаменима для разработчиков, работающих с файлами на сервере.
Введение в функцию feof() в PHP
Функция feof() в PHP проверяет, достигнут ли конец файла (EOF) для открытого файлового указателя. При чтении файла с помощью таких функций, как fgets() или fread(), PHP поддерживает внутренний курсор, который перемещается при каждом чтении. feof() возвращает true после того, как попытка чтения выходит за пределы последнего байта.
На этой странице описаны синтаксис feof(), одна тонкость, которая часто вводит людей в заблуждение (в какой именно момент она возвращает true), рекомендуемый шаблон цикла и распространённая ошибка, которой следует избегать.
Если вы только начинаете работать с открытием и чтением файлов, начните с Открытие и чтение файла в PHP.
Синтаксис
Синтаксис функции feof() выглядит следующим образом:
Синтаксис PHP для feof()
bool feof ( resource $stream )$stream: файловый указатель (ресурс) для проверки.- Возвращает:
bool—true, если файловый указатель находится в конце файла или произошла ошибка,falseв противном случае.
Параметры
Функция feof() принимает один обязательный параметр:
$stream: файловый указатель, который вы хотите проверить. Это должен быть корректный ресурс, открытый с помощьюfopen()(или аналогичной функции работы с потоками), и он должен оставаться открытым — передача указателя, который уже был закрыт с помощьюfclose(), или чего-либо, что не является ресурсом, вызовет предупреждение.
Как определяется EOF (важный нюанс)
feof() не смотрит вперёд. Она возвращает true только после того*, как функция чтения, например fgets() или fread(), уже попыталась прочитать данные за пределами конца файла:
- Проверка
feof()сразу послеfopen(), до какого-либо чтения, всегда возвращаетfalse— даже для пустого файла. - Файл, заканчивающийся символом новой строки, считается полностью прочитанным только тогда, когда чтение после последней строки ничего не возвращает; именно это финальное чтение переключает
feof()вtrue.
По этой причине надёжный способ чтения файла — проверять возвращаемое значение функции чтения, а не только feof(). Для непоискового потока (сетевого сокета или канала) feof() также может вернуть true только после закрытия соединения, поэтому опираться на результат чтения безопаснее и в этом случае.
Примеры
Ниже приведены примеры использования функции feof():
Пример 1: Проверка достижения конца файла после чтения
Следующий пример читает первую строку файла, а затем проверяет, достигнут ли конец:
Проверка достижения конца файла в PHP
<?php
$fileHandle = fopen("example.txt", "r");
// Read the first line
$firstLine = fgets($fileHandle);
// Now check if we've reached the end
if (feof($fileHandle)) {
echo "End of file reached";
} else {
echo "End of file not reached";
}
fclose($fileHandle);
?>Пример 2: Стандартный шаблон цикла (рекомендуется)
Самый чистый и безопасный способ читать файл построчно — зацикливаться на возвращаемом значении fgets(): при достижении конца файла она возвращает false, поэтому явно вызывать feof() не нужно. Этот шаблон также позволяет избежать ловушки с бесконечным циклом, описанной ниже:
Стандартный цикл чтения в PHP
<?php
$fileHandle = fopen("example.txt", "r");
if ($fileHandle === false) {
die("Error: Could not open file.");
}
while (($line = fgets($fileHandle)) !== false) {
echo $line;
}
fclose($fileHandle);
?>Это выводит каждую строку файла до тех пор, пока не будет достигнут конец.
Пример 3: Автономная запускаемая демонстрация
В этом примере создаётся временный файл, записываются три строки, а затем он читается обратно с помощью feof(), чтобы точно показать, в какой момент EOF переключается в true:
Демонстрация поведения feof()
<?php
$path = tempnam(sys_get_temp_dir(), "demo");
file_put_contents($path, "line 1\nline 2\nline 3\n");
$fh = fopen($path, "r");
var_dump(feof($fh)); // false — nothing read yet
while (!feof($fh)) {
$line = fgets($fh);
if ($line === false) {
break; // read failed / past EOF
}
echo "Read: " . trim($line) . "\n";
}
var_dump(feof($fh)); // true — last read passed EOF
fclose($fh);
unlink($path);
?>Ожидаемый вывод:
bool(false)
Read: line 1
Read: line 2
Read: line 3
bool(true)Распространённая ошибка: бесконечный цикл
Вызов fgets() без проверки возвращаемого значения внутри цикла while (!feof($fh)) рискован. Если возникнет ошибка чтения (или поток никогда не сообщит об EOF), feof() никогда не станет true и цикл будет работать бесконечно. Всегда совмещайте проверку EOF с результатом чтения — или, проще говоря, зацикливайтесь непосредственно на fgets(), как в Примере 2.
Связанные функции
fopen()— открывает файл и получает указатель, который проверяетfeof().fgets()— читает одну строку за раз.fread()— читает фиксированное количество байт.fclose()— закрывает указатель по завершении работы.
Заключение
Функция feof() сообщает, вышло ли чтение за пределы конца открытого файла. Самое важное правило: она переключается в true только после попытки чтения, поэтому в безопасных циклах по файлу следует проверять возвращаемое значение fgets() или fread() напрямую. С таким шаблоном вы избежите как преждевременных выходов, так и бесконечных циклов.