fgets()
The fgets() function is a built-in function in PHP that reads a single line from a file. The function reads a line of text from the file and returns it as a
The fgets() function reads one line at a time from an open file handle. It is the standard way to process text files in PHP without loading the whole file into memory — which matters when a file is large enough that reading it all at once (with file_get_contents() or fread()) would be wasteful or impossible.
This page covers the syntax, what fgets() returns, the correct read loop, common gotchas, and how it relates to the other file-reading functions.
What is the fgets() Function?
fgets() reads from the current position of an open file handle up to and including the next newline character (\n), and returns that text as a string. It then advances the file pointer so the next call reads the next line.
It is not limited to files on disk: any stream opened with fopen() works, including php://stdin for reading keyboard input and remote URLs.
Syntax
fgets(resource $stream, ?int $length = null): string|false$stream— a file pointer returned byfopen()(or another stream function). It must still be open.$length(optional) — read at most$length - 1bytes. Reading stops when a newline is reached, the end of file is reached, or$length - 1bytes have been read, whichever comes first. Omit it to read to the end of the line no matter how long.
What fgets() returns
| Situation | Return value |
|---|---|
| A line was read | The line as a string, with the trailing \n included |
| Already at end of file | false |
| An error occurred | false |
Because the newline is kept, echo reproduces the file's line breaks. If you don't want them, strip with rtrim($line, "\r\n").
The fact that
fgets()returnsfalseat end-of-file is what makes the read loop below work — you don't even needfeof().
How to Use fgets(): the three steps
- Open the file with
fopen()in a read mode such as"r". - Read line by line with
fgets(). - Close the handle with
fclose()when done.
The recommended read loop
The cleanest pattern uses the false return value as the loop condition. Assignment in PHP evaluates to the assigned value, so while (($line = fgets($file)) !== false) reads a line and tests it in one step:
<?php
$file = fopen("file.txt", "r");
if ($file === false) {
exit("Could not open the file.\n");
}
while (($line = fgets($file)) !== false) {
echo $line; // newline is already part of $line
}
fclose($file);The strict !== false comparison matters: a line containing only "0" is "falsy" in PHP, so a plain while ($line = fgets($file)) would stop early on that line. Always compare with !== false.
Reading line by line with feof()
You will also see the loop written with feof(), which returns true once the end of file has been reached:
<?php
$file = fopen("file.txt", "r");
while (!feof($file)) {
$line = fgets($file);
if ($line === false) {
break; // guard against a read failure mid-loop
}
echo $line;
}
fclose($file);Both styles are correct. The !== false version is usually preferred because feof() only becomes true after a read has failed, which can cause one extra empty iteration if you're not careful.
Limiting the line length
Pass $length to cap how much of a long line you read at once. Here only the first 9 bytes ($length - 1) of each chunk are returned:
<?php
$file = fopen("file.txt", "r");
// "Hello, world!" is read in pieces of at most 9 bytes
echo fgets($file, 10); // "Hello, wo"
echo "\n";
echo fgets($file, 10); // "rld!" (rest of the line)
fclose($file);This is handy for guarding against pathologically long lines, but for normal text files you can leave $length off.
Reading user input from the terminal
Because fgets() works on any stream, it is the classic way to read a line typed by the user on the command line:
<?php
echo "What is your name? ";
$name = rtrim(fgets(STDIN), "\r\n"); // strip the Enter key's newline
echo "Hello, $name!\n";STDIN is a predefined constant for php://stdin.
Common gotchas
- The trailing newline is included. Use
rtrim($line, "\r\n")when comparing or storing values. - Test with
!== false, not just truthiness, so lines like"0"or""don't end the loop early. fgets()needs a valid, open handle. Iffopen()returnedfalse(missing file, wrong permissions), passing it tofgets()triggers a warning. Check the handle first.- Don't forget
fclose(). PHP closes handles at script end, but freeing them explicitly is good practice, especially in long-running scripts. - For whole-file reads, prefer simpler tools. If you don't need line-by-line control,
file()returns the file as an array of lines andfile_get_contents()returns it as one string.
Related functions
fopen()— open a file or stream (required beforefgets()).fread()— read a fixed number of bytes, not lines.fgetc()— read a single character.fgetcsv()— read a line and parse it as CSV.feof()— test for end of file.fclose()— close the handle.
Conclusion
fgets() reads a file one line at a time, returning each line (newline included) until it hits the end of file, where it returns false. Pair it with fopen() and fclose(), drive the loop with a strict !== false test, and remember to rtrim() the newline when you need the clean value. For very large files this keeps memory use flat, making fgets() the go-to choice for streaming text in PHP.