W3docs

ftell()

Функция ftell() в PHP возвращает текущую позицию указателя файла — байтовое смещение от начала файла.

Что такое функция ftell()?

Функция ftell() — встроенная функция PHP, которая возвращает текущую позицию файлового указателя — байтовое смещение от начала файла, на котором произойдёт следующая операция чтения или записи. Каждый открытый дескриптор файла хранит внутренний курсор; функции fread(), fwrite() и fgets() продвигают его вперёд, а fseek() и rewind() перемещают его явно. ftell() просто сообщает, где находится этот курсор в данный момент, не изменяя его.

Знание смещения полезно, когда нужно запомнить текущее положение в файле (чтобы потом вернуться к нему с помощью fseek()), подсчитать количество прочитанных байт или обнаружить конец записи в файле с фиксированной шириной записи или в двоичном файле.

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

Синтаксис

ftell(resource $stream): int|false

$stream должен быть файловым указателем, возвращённым функцией fopen() (или такой функцией, как fsockopen()). Функция возвращает позицию в виде целочисленного байтового смещения или false в случае ошибки — например, если поток не поддерживает позиционирование. Поскольку 0 (начало файла) является допустимым «ложным» результатом, всегда проверяйте возвращаемое значение с помощью ===:

$pos = ftell($file);
if ($pos === false) {
    // could not determine the position
}

Как использовать функцию ftell()

Типичный порядок действий:

  1. Откройте файл с помощью fopen() в нужном режиме.
  2. Прочитайте данные из файла или запишите их, чтобы указатель переместился.
  3. Вызовите ftell() с файловым указателем, чтобы узнать его позицию.
  4. Используйте полученное смещение — например, сохраните его или передайте в fseek().
  5. Закройте файл с помощью fclose().

Приведённый ниже пример полностью самодостаточен: он сначала создаёт временный файл, поэтому вы можете запустить его без предварительной подготовки данных.

<?php

// Create a temporary file with known contents.
$filename = tempnam(sys_get_temp_dir(), 'demo');
file_put_contents($filename, 'Hello, World! This is a test.');

$file = fopen($filename, 'r');

echo "Start position: " . ftell($file) . "\n";   // 0

fread($file, 5);                                  // read "Hello"
echo "After reading 5 bytes: " . ftell($file) . "\n";  // 5

fread($file, 5);                                  // read ", Wor"
echo "After reading 5 more: " . ftell($file) . "\n";   // 10

rewind($file);                                    // jump back to the start
echo "After rewind: " . ftell($file) . "\n";      // 0

fseek($file, 7);                                  // jump to byte 7
echo "After fseek to 7: " . ftell($file) . "\n";  // 7
echo "Next 5 bytes: " . fread($file, 5) . "\n";   // "World"

fclose($file);
unlink($filename);

Вывод:

Start position: 0
After reading 5 bytes: 5
After reading 5 more: 10
After rewind: 0
After fseek to 7: 7
Next 5 bytes: World

Каждый вызов fread() смещает указатель на количество фактически прочитанных байт, поэтому ftell() возвращает последовательно 0, 5, затем 10. rewind() сбрасывает указатель в 0, а fseek($file, 7) перемещает его прямо к байту 7, с которого начинается слово World.

Режим дозаписи: распространённый подводный камень

Когда файл открыт в режиме дозаписи ('a' или 'a+'), каждая запись всегда выполняется в конец файла, независимо от текущей позиции указателя. Сразу после открытия ftell() может вернуть 0, хотя записи будут добавляться в конец — его возвращаемое значение в режиме дозаписи не отражает достоверно позицию следующей записи. Если нужны точные позиции, открывайте файл с 'r+', 'w+' или 'c+' и явно перемещайте указатель.

Аналогичная ситуация с непозиционируемыми потоками (например, некоторыми сетевыми потоками или каналами): они не могут сообщить осмысленную позицию, и ftell() возвращает для них false.

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

ftell() редко используется в одиночку. Она входит в небольшое семейство функций управления файловым указателем:

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

Для общего обзора см. Работа с файлами в PHP.

Заключение

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

Практика

Практика
Что делает функция ftell() в PHP?
Что делает функция ftell() в PHP?
Was this page helpful?