0

I am fairly new to PHP and just trying to convert something I did in C. The idiom for reading from a file in C that I was taught was:

while ((c = getchar()) != EOF) {
    doSomethingWith(c);
}

I've done some reading and it would seem that the 'right' way to do this in PHP is:

while (!feof($file)) {
    $c = fgetc($file);
    doSomethingWith($c);
}

My question is: Is it ok to combine the two as follows (I have tried it, and its working ok on my test file), or are there situations where this could find a null before EOF?:

while (($c = fgets($f)) != null) {
    doSomethingWith($c);
}

Cheers in advance

Steve

Steve
  • 1,439
  • 2
  • 14
  • 27
  • *(tip)* [Iterating file contents with Spl](http://gooh.posterous.com/iterating-files-with-spl) – Gordon Jun 23 '11 at 10:52
  • Thanks Gordon. Is using that SPL method more PHP-correct? (If this was Python I'd say, "Is this more Pythonic?" - not sure if that translates to PHP... Python people sometimes seem like they have a carrot stuck somewhere when it comes to how things should be done and doing things Pythonically :) – Steve Jun 23 '11 at 21:19
  • No. You can use both. I just find the SPL way more convenient, versatile and readable. But that's just me. Use what suits you. – Gordon Jun 23 '11 at 23:48

2 Answers2

2

It's ok, but the way you are doing it it's wrong (at least "not correct at all"). fgets() returns false, if the end of the file is reached, thus you should test against false instead. It works for you, because you use the "simple" equality operator (==), that will case null to false, when comparing against a boolean.

Returns a string of up to length - 1 bytes read from the file pointed to by handle. If there is no more data to read in the file pointer, then FALSE is returned.

If an error occurs, FALSE is returned.

This means, it have to look like

while (($c = fgets($f)) !== false) {
    doSomethingWith($c);
}
Community
  • 1
  • 1
KingCrunch
  • 128,817
  • 21
  • 151
  • 173
  • Ah, appreciate the edit... I'll look up the different equality operators and make better use of documentation. If it returns false, then could I have just done "while($c = fgets($f))"? Cheers, Steve – Steve Jun 23 '11 at 10:49
  • Maybe. In this context, I wouldn't suggest it, because this will cast everything else to a boolean too (its identical to `($c = fgets($f)) == true)`), which means, that `0` and `""` will result in `false`. Here `fgets()` should always return the newline-character too, thus it _should_ work, but I wouldn't rely on it ;) – KingCrunch Jun 23 '11 at 10:54
  • I just read the documentation - and apparently I can't do as I suggested in the above comment as a "0" or "" _MAY_ equate to a false... so I will stick with the boolean equality operator. Thanks again, you and Jon got me pointed in the right direction... – Steve Jun 23 '11 at 10:55
0

fgets is documented to return false when there is no more data to read. Therefore, the technically correct solution would be

// Notice the !== [non-identical] operator below
while (($c = fgets($f)) !== false) {
    doSomethingWith($c);
}

This is better because fgets could legitimately return an empty (zero-length) string, which would compare equal to null when using the equality operator. The operator !== also checks the type of its operands, so this way you are covered.

Jon
  • 428,835
  • 81
  • 738
  • 806