php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51933 file_put_contents(...,FILE_APPEND|LOCK_EX) wrongly documented
Submitted: 2010-05-27 19:09 UTC Modified: 2010-10-23 02:07 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: dxjones at gmail dot com Assigned: cataphract (profile)
Status: Closed Package: Documentation problem
PHP Version: Irrelevant OS: ALL
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: dxjones at gmail dot com
New email:
PHP Version: OS:

 

 [2010-05-27 19:09 UTC] dxjones at gmail dot com
Description:
------------
This is a bug in the PHP documentation.
I verified the bug using PHP 5.2.10, but the problem is not in the code; it is in the description.

The doc INCORRECTLY states that FILE_APPEND and LOCK_EX are "mutually exclusive".  This is just plain false.  It also says something wonky about appends being atomic.

Here is what I did to demonstrate the error.

1. I create a script "race.php" that appends to a file "race.csv"
2. The key line is:
file_put_contents('race.csv', $s, FILE_APPEND);
3. I use a tool "Jakarta" to generate a large amount of traffic (5000 fetches in just a few seconds).
3. When I look at the output file, there are fewer than 5000 lines.
4. I repeat the same experiment with a flag to use this key line:
file_put_contents('race-lock.csv', $s, FILE_APPEND|LOCK_EX);
5. The output file has exactly 5000 lines.

This proves there is an error in the documentation.

Goodness knows how much damage this error has caused.
For me, there were corrupted log files in several large online applications.
The error only manifests when there is heavy traffic and multiple PHP processes trying to append to the same file at the same time.

The documentation falsely instructs developers *NOT* to use "FILE_APPEND|LOCK_EX".

There was even a correct code example in late 2009 that included "FILE_APPEND|LOCK_EX".  Rather than fix the documentation, they CHANGED THE EXAMPLE (!) to remove "LOCK_EX".  Sigh.

Please fix this.


Test script:
---------------
<? // race.php
// you will only see the error if you hit this script many times in a brief period
// so there are multiple PHP processes trying to append to the same file at the same time
// The PHP documentation FALSELY says you can't combine "FILE_APPEND|LOCK_EX"
// Call this script 5000 times within just a few seconds, see if you get 5000 lines of output -- without LOCK_EX, you will LOSE DATA!!

$t = microtime(TRUE);
$alpha = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
$r = rand(0,9);
$w = '';
for ($i = 0 ; $i < 20 ; ++$i) {
	$w .= $alpha[$r];
}
$row = array( $alpha[$r] );
$row[]= sprintf('%.9f', $t);
for ($i = 0 ; $i < 64 ; ++$i) {
	$row[] = $w . sprintf('%02d',$i);
}
$row[] = $alpha[$r];
$row[] = sprintf('%.9f', microtime(TRUE) - $t);

$s = implode(',',$row) . "\n";
if (array_key_exists('reset', $_REQUEST)) {
	system('rm -f race.csv race-lock.csv');
} elseif (array_key_exists('lock', $_REQUEST)) {
	file_put_contents('race-lock.csv', $s, FILE_APPEND | LOCK_EX);
} else {
	file_put_contents('race.csv', $s, FILE_APPEND);
}
?>
<html><head><title>race</title></head><body><h1>race</h1></body></html>


Expected result:
----------------
look inside the output files:
race.csv -- expect to have exactly 5000 lines, but might have fewer than 5000 lines because of error in documentation
race-lock.csv -- will have exactly 5000 lines because FILE_APPEND|LOCK_EX is used



Actual result:
--------------
race.csv -- has fewer than 5000 lines because of error

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-10-23 02:07 UTC] cataphract@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: cataphract
 [2010-10-23 02:07 UTC] cataphract@php.net
I fixed this a while back. See bug #52767.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 02:01:29 2024 UTC