feof

(PHP 3, PHP 4, PHP 5)

feof -- 测试文件指针是否到了文件结束的位置

说明

bool feof ( resource handle )

如果文件指针到了 EOF 或者出错时则返回 TRUE,否则返回一个错误(包括 socket 超时),其它情况则返回 FALSE

警告

如果服务器没有关闭由 fsockopen() 所打开的连接,feof() 会一直等待直到超时而返回 TRUE。默认的超时限制是 60 秒,可以使用 stream_set_timeout() 来改变这个值。

文件指针必须是有效的,并且必须指向一个由 fopen()fsockopen() 成功打开的文件。


add a note add a note User Contributed Notes
Tom
25-Oct-2006 06:27
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...
jorge dot mendes at constante dot pt
08-Jul-2006 12:23
feof() not reliable

I used feof() in a context of retrieving a CSV file into a database.

I had the following code:

while(!feof($file_handler)){

  $row = fgets($file_handler);
  (...)

}

I was processing several files, and in some of them, the last row was duplicated, so I assume that feof() is not reliable.

That's how I solved the problem:

while($row = fgets($file_handler)){
 
  (...)

}
ironoxid at libero dot it
06-Jun-2006 09:52
I really thought that the feof() was TRUE when the logical file pointer is a EOF.
but no !
we need to read and get an empty record before the eof() reports TRUE.

So

$fp = fopen('test.bin','rb');
while(!feof($fp)) {
  $c = fgetc($fp);
  // ... do something with $c
  echo ftell($fp), ",";
}
echo 'EOF!';

prints for two time the last byte position.
If our file length is 5 byte this code prints

0,1,2,3,4,5,5,EOF!

Because of this, you have to do another check to verify if fgetc really reads another byte (to prevent error on "do something with $c" ^_^).

To prevent errors you have to use this code

$fp = fopen('test.bin','rb');
while(!feof($fp)) {
  $c = fgetc($fp);
  if($c === false) break;
  // ... do something with $c
}

but this is the same of

$fp = fopen('test.bin','rb');
while(($c = fgetc($fp))!==false) {
  // ... do something with $c
}

Consequently feof() is simply useless.
Before write this note I want to submit this as a php bug but one php developer said that this does not imply a bug in PHP itself (http://bugs.php.net/bug.php?id=35136&edit=2).

If this is not a bug I think that this need at least to be noticed.

Sorry for my bad english.
Bye ;)
m a p o p a at g m a i l. c o m
03-Jun-2006 08:58
you  can avoid the infinite loop and filling the error logs
by an simple if statement
Here is the example

   $handle = fopen("http://xml.weather.yahoo.com/forecastrss?p=AYXX0008&u=f", "r");
   $xml = "";
   if ($handle)
   {
       while (!feof($handle))
       {
           $xml .= fread($handle, 128);
       }
       fclose($handle);
   }
docey
13-Jan-2006 03:07
because using an invalid handle can couse seriuos trouble,
here is some very simple code that can prevent any piece
of code to runaway using an invalid handle.

function is_valid(&$fp, $type){
 if(is_resource($fp)){
   if(get_resource_type($fp) == $type){
   return true;
   }else{
   return false;
   }
 }else{
  return false;
 }
}

now all you need to do to check if you got a valid handle,

if(is_valid($fp, "file")){
 // your code
}else{
 // your error code
}

its that simple to prevent any of your code from using an
invalid handle. ofcourse you can change the "file" line to
any resource you want to check for invalidies.

please use good coding habits, and don't assume any
varialbles, resource or objects are good. check them!!
02-Jan-2006 10:27
if you use fseek function to pos the pointer exceed the size the file,feof still return true.so note that when you use feof as the condition of while loop.
info at derlange dot tk
06-Aug-2005 06:20
NOTE!
if your file is empty and you make the feof()-check, it will return true the first time you call it.
example:
$handle=fopen("file","r");
while(!feof($handle))
{
 $line=fgets($handle);
}
$line is now an empty string ( "" )

you have to check the size of your file before, like this sample code:
if (filesize("file")>0)
{
 while( !feof($handle) )
 {
  $zeile=fgets($handle);
 }
}
01-Aug-2005 01:21
if you hit an feof() infinite loop, watch out for resultant humongous logs, they can cripple a site with hard disk usage limits or run up excess usage fees.
05-Mar-2005 01:02
if you're worried the file pointer is invalid, TEST IT before you go into your loop... that way it'll never be an infinite loop.
bruno dot moreira at brturbo dot com
13-Jan-2005 07:43
Use it with many caution. If your php.ini don't stop the script when it enter a infinity loop.
I don't think as good the use of feof with an while loop.
See the example:
$a=open("/etc/passwd");
while(!feof($a)){
 echo fgets($a);
 }
I used '/etc/passwd' because obviously the apache user isn't root, then cannot read '/etc/passwd'.
If in future the feof return's some different that TRUE or FALSE, this can be used with good results.
mark at newfangled dot com
05-May-2004 01:39
When a fopen() is done on a file that has permissions that are set to
not allow the current process user to read it or the file doesn't exist
it returns false. This is expected. The problem is when feof() is fed
the invalid handle it doesn't return TRUE() thus creating an infinite
loop in the following code example.

<?php
$fp
= fopen( 't.txt', 'r' );

while( !
feof( $fp ) )
{
   print
fgets( $fp );
}

fclose( $fp );
?>

feof() would return TRUE to cancel the loop and the script would end.
There would of course be warnings because of the invalid file handle,
but that is expected.

There should be better error handling on the developers part and catch
the invalid file handle, but I would expect the file functions to handle
this situation accordingly.
Johannes
12-Mar-2004 06:47
I found feof() to be a slow function when using a non-blocking connection.

The function stream_get_meta_data() returns much quicker and has a return field 'eof'.