feof() is, in fact, reliable. However, you have to use it carefully in conjunction with fgets(). A common (but incorrect) approach is to try something like this:



<?

$fp = fopen("myfile.txt", "r");

while (!feof($fp)) {

$current_line = fgets($fp);

// do stuff to the current line here

}

fclose($fp);

?>



The problem when processing plain text files is that feof() will not return true after getting the last line of input. You need to try to get input _and fail_ before feof() returns true. You can think of the loop above working like this:



* (merrily looping, getting lines and processing them)

* fgets used to get 2nd to last line

* line is processed

* loop back up -- feof returns false, so do the steps inside the loop

* fgets used to get last line

* line is processed

* loop back up -- since the last call to fgets worked (you got the last line), feof still returns false, so you do the steps inside the loop again

* fgets used to try to get another line (but there's nothing there!)

* your code doesn't realize this, and tries to process this non-existent line (typically by doing the same actions again)

* now when your code loops back up, feof returns true, and your loop ends



There's two ways to solve this:



1. You can put an additional test for feof() inside the loop

2. You can move around your calls to fgets() so that the testing of feof() happens in a better location



Here's solution 1:



<?

$fp = fopen("myfile.txt", "r");

while(!feof($fp)) {

$current_line = fgets($fp);

if (!feof($fp)) {

// process current line

}

}

fclose($fp);

?>



And here's solution 2 (IMHO, more elegant):



<?

$fp = fopen("myfile.txt", "r");

$current_line = fgets($fp);

while (!feof($fp)) {

// process current line

$current_line = fgets($fp);

}

fclose($fp);

?>



FYI, the eof() function in C++ works the exact same way, so this isn't just some weird PHP thing...