Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP's feof behavior versus C's

Tags:

php

feof

I come from a C and C++ background but also play with some web stuff. All us C folks (hopefully) know that calling feof on a FILE* before doing a read is an error. This is something that stings newbies to C and C++ very often. Is this also the case for PHP's implementation?

I figure it has to be because the file could be a socket or anything else where it is impossible to know the size before finishing reading. But just about every PHP example (even those found on php.net I've seen looks something like this (and alarms go off in my head):

$f = fopen("whatever.txt", "rb");
while(!feof($f)) {
    echo fgets($f);
}
fclose($f);

I know it is preferable to write this like this and avoid this issue:

$f = fopen("whatever.txt", "rb");
while($line = fgets($f)) {
    echo $line;
}
fclose($f);

but that's besides the point. I tried testing if things would fail if I did it "the wrong way", but I could not get it to cause incorrect behavior. This isn't exactly scientific, but I figured it was worth a try.

So, is it incorrect to call feof before an fread in PHP?

There are a couple of ways that PHP could have done this differently that C's version, but I feel they have downsides.

  • they could have it default to !EOF. This is sub-optimal because it may be incorrect for some corner cases.

  • they could get the file size during an fopen call, but this couldn't work on all types of file resources, yielding inconsistent behavior and would be slower.

like image 219
Evan Teran Avatar asked Jul 13 '10 16:07

Evan Teran


1 Answers

PHP doesn't know whether it's at the end of the file until you've tried to read from it. Try this simple example:

<?php 
$fp = fopen("/dev/null","rb"); 
while (!feof($fp)) { 
    $data = fread($fp, 1);
    echo "read " . strlen($data) . " bytes";  
} 
fclose($fp); 
?>

You will get one line reading read 0 bytes. feof() returned true even though you were technically at the end of the file. Usually this doesn't cause a problem because fread($fp, 1) returns no data, and whatever processing you're doing on that handles no data just fine. If you really do need to know if you're at the end of the file, you do have to do a read first.

like image 187
MightyE Avatar answered Oct 15 '22 00:10

MightyE