php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #16708 fgets handling of non-unix EOL markers
Submitted: 2002-04-19 18:12 UTC Modified: 2002-09-26 10:46 UTC
From: liamr at umich dot edu Assigned:
Status: Closed Package: Filesystem function related
PHP Version: 4.1.2 OS: Solaris 2.x
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
43 - 24 = ?
Subscribe to this entry?

 
 [2002-04-19 18:12 UTC] liamr at umich dot edu
Currently, fgets() only recognizes \n (LF) as the end of line marker.  It would be useful if it would also recognize CR/LF (pc) and CR (mac).

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-04-20 05:37 UTC] tal@php.net
It works fine on windows and on mac. If it still doesn't work, provide the relevant code and reopen the report.

-Tal
 [2002-04-20 11:00 UTC] liamr at umich dot edu
On Solaris, fgets doesn't recognize EOL other than LF.

This code is used in the following examples...
<pre>
<?php

$filename = "/tmp/tsv";
$delimiter = "\t";

$fp = fopen($filename, 'r');
if (!$fp) return false;

$data = array();

if ($header) $head = explode($delimiter, fgets($fp, 1024));

while ($line = fgets($fp, 1024)) {
        $line = explode($delimiter, $line);
        if (!isset($head)) $data[] = $line;
        else {
                $newline = array();
                for ($i=0; $i<count($head); $i++) {
                        //if (!empty($line[$i]))
                        $newline[$head[$i]] = 
empty($line[$i]) ? '' : $line[$i];
                }
                $data[] = $newline;
        }
}

fclose($fp);

print_r($data);
?>

This file was created on macintosh using Simpletext and 
scp'd to a sun:
cat	dog	hat
dad	mom	boy
you	wow	sun

When you look at it w/ "od -a" on solaris (octaldump, with 
the "show named characters" flag), it looks like:

0000000  c  a  t ht  d  o  g ht  h  a  t cr  d  a  d  ht
0000020  m  o  m ht  b  o  y cr  y  o  u ht  w  o  w  ht
0000040  s  u  n ht
0000044

And the above php code creates this output:

Array
(
    [0] => Array
        (
            [0] => cat
            [1] => dog
            [2] => hat
dad
            [3] => mom
            [4] => boy
you
            [5] => wow
            [6] => sun
            [7] => 
        )

)

od of the same file created with vi on solaris looks like:

0000000  c  a  t ht  d  o  g ht  h  a  t nl  d  a  d ht
0000020  m  o  m ht  b  o  y nl  y  o  u ht  w  o  w ht
0000040  s  u  n nl
0000044

and the output from the php code looks like:

Array
(
    [0] => Array
        (
            [0] => cat
            [1] => dog
            [2] => hat

        )

    [1] => Array
        (
            [0] => dad
            [1] => mom
            [2] => boy

        )

    [2] => Array
        (
            [0] => you
            [1] => wow
            [2] => sun

        )

)

For a file created on a PC, I imagine the resulting data 
would look right, but the last element of every array would 
contain an unseen CR.

The different platforms use of different eol markers.  This 
is widely acknowledged.  Look at the last few users 
comments in the documentation for fgets, 
http://www.php.net/manual/en/function.fgets.php:

"...Note that fgets() does not cope with MAC newlines (i.e. 
a single CR character, or "\r")..."

"...If you are doing cross platform development where your
PHP programs need to run on windows, unix and macs, or even 
are reading from files that were developed on various 
platforms, do not (I repeat DO NOT) use fgets().  This is 
because fgets(), as mentioned before, does not deal with 
carriage returns and line feeds for all systems..."
 [2002-04-20 11:05 UTC] liamr at umich dot edu
I forgot to change the status when I posted my last 
comment.
 [2002-04-20 11:45 UTC] sniper@php.net
This is actually a bug. There is also similar bug #16521

 [2002-09-26 10:46 UTC] wez@php.net
This bug has been fixed in CVS.

In case this was a PHP problem, snapshots of the sources are packaged
every three hours; this change will be in the next snapshot. You can
grab the snapshot at http://snaps.php.net/.
 
In case this was a documentation problem, the fix will show up soon at
http://www.php.net/manual/.

In case this was a PHP.net website problem, the change will show
up on the PHP.net site and on the mirror sites in short time.
 
Thank you for the report, and for helping us make PHP better.


 [2004-08-06 03:25 UTC] nitinchopra at hotmail dot com
Working on Sun 5.8.

I have an output that looks like the following- separated by lots of spaces and NOT <TAB>. How can I massage this data so that the spaces between the year, 2004 and 0 AND 0 and 3 become TAB?
Thu Aug 5 19:41:00 EDT 2004               0       3
Thu Aug 5 19:41:00 EDT 2004               0       3
Thu Aug 5 19:41:00 EDT 2004               0       3
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 07:01:29 2024 UTC