PHP Doku:: Prüft, ob der Dateizeiger am Ende der Datei steht - function.feof.html

Verlauf / Chronik / History: (1) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzDateisystemrelevante ErweiterungenDateisystemDateisystem-Funktionenfeof

Ein Service von Reinhard Neidl - Webprogrammierung.

Dateisystem-Funktionen

<<fclose

fflush>>

feof

(PHP 4, PHP 5)

feofPrüft, ob der Dateizeiger am Ende der Datei steht

Beschreibung

bool feof ( resource $handle )

Gibt TRUE zurück, falls der Dateizeiger am Ende der Datei steht oder ein Fehler aufgetreten ist, andernfalls FALSE.

Der Dateizeiger muss gültig sein, d.h. die Datei, auf die gezeigt wird, muss zuvor mit fopen(), popen() oder fsockopen() geöffnet worden sein.


13 BenutzerBeiträge:
- Beiträge aktualisieren...
kexianbin at diyism dot com
9.06.2010 10:16
The forgotten function to detect if it is at the last line in many language:

<?php
function llof($fp) {
         {
$p_current=ftell($fp);
         
$rtn=fgets($fp)?false:true;
         
fseek($fp, $p_current);
          return
$rtn;
}
?>
sudo dot adam dot carruthers at gmail dot com
7.02.2010 6:01
When using feof() on a TCP stream, i found the following to work (after many hours of frustration and anger):

NOTE: I used ";" to denote the end of data transmission.  This can be modified to whatever the server's end of file or in this case, end of output character is.

<?php
        $cursor
= "";
       
$inData = "";

        while(
strcmp($cursor, ";") != 0) {
           
$cursor = fgetc($sock);
           
$inData.= $cursor;
        }
       
fclose($sock);
        echo(
$inData);
?>

Since strcmp() returns 0 when the two strings are equal, it will return non zero as long as the cursor is not ";".  Using the above method will add ";" to the string, but the fix for this is simple.

<?php
        $cursor
= "";
       
$inData = "";

        
$cursor = fgetc($sock);
        while(
strcmp($cursor, ";") != 0) {
           
$inData.= $cursor;
        }
       
fclose($sock);
        echo(
$inData);
?>

I hope this helps someone.
jakicoll
3.01.2010 1:59
Please note that feof() used with TCP-Connections, returns false as long as the connection is open.
It even returns false when there is no data available.

BTW: Using feof() with HTTP for a single request, you should always make sure that you set the HTTP-Header "Connection" to "close" and _not_ to "keep-alive".
honzam+php at ipdgroup dot com
28.02.2008 11:17
Johannes: Remember note from stream_get_meta_data page: For socket streams this member [eof] can be TRUE  even when unread_bytes  is non-zero. To determine if there is more data to be read, use feof() instead of reading this item.

Another thing: better not rely on the "including socket timeout" part of when feof returns true. Just found program looping two days in while(!feof($fd)) fread ... with 20 seconds timeout in PHP 4.3.10.
Jet
19.09.2007 16:03
To avoid infinite loop with fgets() just use do..while statement.

<?php
if ($f = fopen('myfile.txt', 'r')) do {
   
$line = fgets($f);
   
// do any stuff here...
} while (!feof($f));
fclose($f);
cmr at forestfactory dot de
19.11.2006 17:57
Here's solution 3:

<?
$fp
= fopen("myfile.txt", "r");
while ( (
$current_line = fgets($fp)) !== false ) {
 
// do stuff to the current line here
}
fclose($fp);
?>

AFAICS fgets() never returns an empty string, so we can also write:

<?
$fp
= fopen("myfile.txt", "r");
while (
$current_line = fgets($fp) ) {
 
// do stuff to the current line here
}
fclose($fp);
?>
Tom
25.10.2006 0: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...
ironoxid at libero dot it
6.06.2006 15: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
3.06.2006 14: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);
    }

2.01.2006 3: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.

1.08.2005 7: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.

4.03.2005 18: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.
Johannes
12.03.2004 11: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'.



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)