ftell()
The ftell() function is a built-in PHP function that returns the current position of the file pointer for the specified file. This function is used to determine
What is the ftell() Function?
The ftell() function is a built-in PHP function that returns the current position of the file pointer — the byte offset, counted from the beginning of the file, where the next read or write will happen. Every open file handle keeps an internal cursor; fread(), fwrite(), and fgets() advance it, while fseek() and rewind() move it explicitly. ftell() simply reports where that cursor currently sits without changing it.
Knowing the offset is useful when you need to record where you are in a file (so you can resume later with fseek()), measure how many bytes you have consumed so far, or detect the end of a record in a fixed-width or binary file.
This page covers the syntax, a runnable example, the value ftell() returns, common gotchas (append mode, streams), and how it relates to the other file-pointer functions.
Syntax
ftell(resource $stream): int|false$stream must be a file pointer returned by fopen() (or a function like fsockopen()). The function returns the position as an integer byte offset, or false on failure — for example if the stream is not seekable. Because 0 (the start of the file) is a valid, "falsy" result, always test the return value with ===:
$pos = ftell($file);
if ($pos === false) {
// could not determine the position
}How to Use the ftell() Function
The typical flow is:
- Open the file with
fopen()in the mode you need. - Read from or write to the file so the pointer moves.
- Call
ftell()with the file pointer to read its position. - Use that offset — for example, store it or pass it to
fseek(). - Close the file with
fclose().
The example below is fully self-contained: it writes a temporary file first, so you can run it as-is without preparing any data.
<?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);Output:
Start position: 0
After reading 5 bytes: 5
After reading 5 more: 10
After rewind: 0
After fseek to 7: 7
Next 5 bytes: WorldEach fread() advances the pointer by the number of bytes it actually read, so ftell() grows from 0 to 5 to 10. rewind() resets it to 0, and fseek($file, 7) moves it directly to byte 7, where the word World begins.
Append Mode: A Common Gotcha
When a file is opened in append mode ('a' or 'a+'), every write goes to the end of the file regardless of where the pointer is. ftell() may report 0 right after opening even though writes land at the end — its return value does not reliably describe where the next write will go in append mode. If you need precise positions, open the file with 'r+', 'w+', or 'c+' and seek explicitly instead.
Likewise, non-seekable streams (such as some network or pipe streams) cannot report a meaningful position and ftell() returns false for them.
Related Functions
ftell() rarely works alone. It is part of a small family of file-pointer functions:
fopen()— open a file and get the pointer thatftell()reads.fread()— read bytes and advance the pointer.fwrite()— write bytes and advance the pointer.fseek()— move the pointer to an absolute or relative position; pair it withftell()to save and restore offsets.rewind()— reset the pointer to the beginning (equivalent tofseek($file, 0)).fclose()— close the file when you are done.
For a broader overview, see PHP File Handling.
Conclusion
The ftell() function reports the current byte offset of a file pointer without moving it, which makes it the natural companion to fseek() and rewind() for navigating files. Remember to compare its result with === false (because 0 is a valid offset), and be aware that append mode and non-seekable streams do not return reliable positions.