fseek()
The fseek() function is a built-in PHP function that sets the file position indicator for the specified file pointer. This function is used to move the file
When PHP reads or writes a file, it keeps an internal cursor — the file position indicator — that marks where the next read or write will happen. Normally that cursor moves forward automatically as you call fread() or fwrite(). The fseek() function lets you move it manually to any byte position, so you can jump backward, skip ahead, or re-read part of a file without closing and reopening it.
This chapter covers the syntax of fseek(), the three whence modes, its return value, and practical patterns like reading a record at a known offset and seeking past the end of a file.
Syntax
fseek(resource $stream, int $offset, int $whence = SEEK_SET): int| Parameter | Description |
|---|---|
$stream | A file pointer returned by fopen(). |
$offset | The number of bytes to move. Can be negative with SEEK_CUR and SEEK_END. |
$whence | The reference point the offset is measured from. Defaults to SEEK_SET. |
fseek() returns 0 on success and -1 on failure. It does not return the new position — use ftell() for that.
The three whence modes
The $whence constant decides where the offset is counted from:
| Constant | Resulting position |
|---|---|
SEEK_SET | offset bytes from the start of the file (the default). |
SEEK_CUR | offset bytes from the current position. |
SEEK_END | offset bytes from the end of the file. Use a negative offset to step back. |
<?php
fseek($file, 10); // 10 bytes from the start (SEEK_SET is implied)
fseek($file, 5, SEEK_CUR); // 5 bytes forward from where we are now
fseek($file, -4, SEEK_END); // 4 bytes before the end of the fileA working example
Let's create a file, then jump to byte 6 and read from there. Because we write and read in the same script, the example is fully self-contained:
<?php
$filename = 'demo.txt';
// Create a file with known contents.
file_put_contents($filename, 'Hello, World!');
$file = fopen($filename, 'r');
fseek($file, 7, SEEK_SET); // move the cursor to byte 7
$data = fread($file, 5); // read 5 bytes: W, o, r, l, d
echo $data; // World
fclose($file);The string 'Hello, World!' is stored as bytes H(0) e(1) l(2) l(3) o(4) ,(5) (6) W(7) o(8) r(9) l(10) d(11) !(12). Seeking to byte 7 lands on the W, and reading 5 bytes prints World.
Always check the return value
Because fseek() returns 0 for success and -1 for failure, compare it explicitly. A loose truthiness check is wrong here — 0 is falsy:
<?php
$file = fopen('demo.txt', 'r');
if (fseek($file, 7) === -1) {
echo "Seek failed";
} else {
echo "Seek succeeded"; // Seek succeeded
}
fclose($file);Things to watch out for
- Not every stream is seekable. Pipes, network sockets, and the
php://stdinstream cannot be sought;fseek()returns-1on them. - Seeking past the end is allowed. With a file opened for writing, you can
fseek()beyond the current end and then write — the gap is filled with\0(null) bytes, creating a sparse region. - Use
SEEK_CURwith append-mode caution. Files opened with mode'a'always write at the end regardless of the cursor;fseek()only affects reads in that mode. fseek()clears the end-of-file flag, so seeking back lets you read data you already passed without reopening the file.
Related functions
ftell()— report the current cursor position (the complement offseek()).rewind()— shortcut forfseek($file, 0).fread()/fwrite()— read or write starting at the cursor.fopen()/fclose()— open and close the stream.
See the PHP File Handling chapter for the bigger picture.
Conclusion
fseek() gives you random access into a file: move the cursor with an $offset measured from SEEK_SET, SEEK_CUR, or SEEK_END, then read or write from the new spot. Remember to check for the -1 return value, pair it with ftell() to know where you are, and keep in mind that not every stream supports seeking.