#16708 [Ana->Csd]: fgets handling of non-unix EOL markers
| From: | wez@php.net | Date: | Thu, 26 Sep 2002 15:46:55 +0000 |
| Subject: | #16708 [Ana->Csd]: fgets handling of non-unix EOL markers | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-20431@lists.php.net to get a copy of this message | ||
ID: 16708
Updated by: wez@php.net
Reported By: liamr@umich.edu
-Status: Analyzed
+Status: Closed
Bug Type: Filesystem function related
Operating System: Solaris 2.x
PHP Version: 4.1.2
New Comment:
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.
Previous Comments:
------------------------------------------------------------------------
[2002-04-20 11:45:07] sniper@php.net
This is actually a bug. There is also similar bug #16521
------------------------------------------------------------------------
[2002-04-20 11:05:47] liamr@umich.edu
I forgot to change the status when I posted my last
comment.
------------------------------------------------------------------------
[2002-04-20 11:00:34] liamr@umich.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 05:37:32] 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-19 18:12:45] liamr@umich.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).
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=16708&edit=1