php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #28371 Different behaviour of fopen depending on r+,w+,a+
Submitted: 2004-05-12 17:20 UTC Modified: 2005-04-29 16:21 UTC
From: rc at opelgt dot org Assigned:
Status: Not a bug Package: Documentation problem
PHP Version: 4.3.4 OS: MacOSX 10.3
Private report: No CVE-ID: None
 [2004-05-12 17:20 UTC] rc at opelgt dot org
Description:
------------
Hello,

for my skill its a bit too much to understand whats 
going on here.

Reproduce code:
---------------
<?php
$alt = '1234567890';
$neu = '13579';

$datei = 'test.txt';
$dh = fopen ($datei,"w");
fwrite($dh, $alt);
fclose($dh);
// pos1
$dh = fopen ($datei,"a+"); // just alter the mode to test others
rewind($dh);
echo "Inhalt<BR>\nalt: ".fread($dh, filesize($datei))."<BR>\n";
ftruncate($dh, '0');
fwrite($dh, $neu);
rewind($dh);
echo 'neu: '.fread($dh, filesize($datei));
fclose($dh);
?>

Expected result:
----------------
I wrote the code above and exspected same behaviour for 
r+, w+ and a+.

Before pos1 The content of 'test.txt' is written to 
'1234567890'.
After pos1 the file is opened anothertime with r+,w+ or 
a+.
Rewind sets the pointer to '0'.
So that fread can read the file from the beginning. 
Ftruncate makes the size of the file to '0' and sets the 
pointer to the beginning of the file.
Fwrite writes the new content and the size of the file 
will be as big as nessessary for the content.
Rewind takes the pointer back from end to beginning of 
the file.

Actual result:
--------------
Echo should tell the new content.
This only works with a+, but with r+ and w+ nothing is 
displayed.

The first echo command tells the 'old' content in a+ and 
r+ mode, but not with w+.

Seems to me there are undocumented differences between 
the modes that makes it difficult to choose and use one 
of them.

R?diger

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-05-12 18:52 UTC] wez@php.net
The output under both linux and OSX is:

Inhalt<BR>
alt: 1234567890<BR>
neu: 13579

Your bug report doesn't sound so much like a bug report, but a support request; this isn't a support forum, so if you don't understand these results even after careful scrutiny of the fopen() manual page, please visit http://www.php.net/support.php to find someone who might be able to help you.
 [2004-05-12 19:12 UTC] rc at opelgt dot org
Do you really think when such strange differences occur 
and the fopen description says nothing about it, its a 
question for support?

Do you know why this differences occurs?

Output with w+ is:
Inhalt<BR>
alt: <BR>
neu: 

and with r+:
Inhalt<BR>
alt: 1234567890<BR>
neu: 

R?diger
 [2004-05-13 14:28 UTC] rc at opelgt dot org
I think it could be mention in the manual:
In PHP 4.2.3 the read pointer for fopen with 'a' is at 
the end of file. Instead in 4.3.4 the pointer is at '0'!
So rewind for reading in 4.3.4 with 'a+' is no longer 
nessessary.

R?diger
 [2004-05-13 15:19 UTC] rc at opelgt dot org
Yes, my sent script runs identically for all modes under 
Linux and MacOSX.
Its different among the modes.

The mode options in fopen() for my understanding should 
have only effect
for the start: position of pointer, content of file, 
file creation if nessessary or not.
Sure, read or write or both ways of access should remain 
until fclose(). ;-)

'r' and 'w' need clearstatcache() but 'a' doesnt.

That is the unexpected and in the manual not mentioned 
difference.
 [2005-02-03 05:05 UTC] sniper@php.net
reclassified

 [2005-03-15 14:24 UTC] vrana@php.net
Please tell us what exactly is not documented. In my eyes, everything works exactly as described on fopen page, mainly in the table "A list of possible modes for fopen() using mode".
 [2005-03-23 01:00 UTC] phpdoc at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2005-03-23 11:53 UTC] rc at opelgt dot org
I have written all things that should be mentioned.

Please read it carefully and if you do not understand 
it, ask me again ;-)
 [2005-03-24 16:09 UTC] vrana@php.net
Tell us what's wrong or missing mainly in the table "A list of
possible modes for fopen() using mode". The behavior of the modes is explained well there IMHO.
 [2005-04-01 01:00 UTC] phpdoc at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2005-04-09 02:10 UTC] rc at opelgt dot org
Which language do you prefer: english or Deutsch?
 [2005-04-13 09:16 UTC] vrana@php.net
Guess! Come on guy, if you want to help us to fix the docs, write something meaningful. This bug fell twice to the state No Feedback, you reopened it twice and now you are asking what's the preferred language???

P.S. English is the preferred language.
 [2005-04-21 01:00 UTC] phpdoc at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2005-04-29 12:49 UTC] techtonik@php.net
To resume.. 

First is bug #32889 : ftruncate doesn't move the file pointer. After file is truncated file pointer is still at 11th position and if you comment first rewind you'll get: 
- in "r+" mode 15 bytes size file
- in "a+" mode filesize == 5 bytes
So, in append mode PHP makes additional fseek to the end of file. Seems logical to me if the same thing will be done in ftruncate.

Next bogus moment in this example is filesize() function - size of the file grows due to the previous bug, but filesize() cache isn't updated. That's why last fread in r+ mode doesn't return newly written string - it reads only first 10 empty bytes occurred after write operation beyond the EOF, while actual content is at bytes 11-15.

Blank output with "w+" mode is documented - this mode erases all previous contents, so there is nothing to read.

 [2005-04-29 16:21 UTC] vrana@php.net
Thus everything is/was already documented.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 20:01:28 2024 UTC