php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70704 fputs
Submitted: 2015-10-13 00:58 UTC Modified: 2015-10-13 01:20 UTC
From: euanmee at gmail dot com Assigned:
Status: Not a bug Package: Filesystem function related
PHP Version: 5.5.30 OS: Windows 7 Home Premium
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: euanmee at gmail dot com
New email:
PHP Version: OS:

 

 [2015-10-13 00:58 UTC] euanmee at gmail dot com
Description:
------------
PHP sometimes only writes part of the string to the disc.

---
From manual page: http://www.php.net/function.fwrite
---

I was originally using Mongoose Web Server - v5.5, with the PHP 5.5.10 supplied with it.

I have now updated to 5.5.30

Three places in my code, I append data to a file.  Occasionally, the first part of the write is not written, i.e. the write is not atomic.

Windows 7 Home Premium, running Mongoose Web Server,using a Western Digital MyBookLive Duo (Debian + ext4) partition mounted as drive M: 




Test script:
---------------
// from getBout.php
$f = fopen("comps/$competitionId/$filename", "a");
// Write the new bout info
fwrite($f, $toWrite);
// Close the -status file
fclose($f);


// from getResults.php
$f = fopen("comps/$competitionId/$filename", "a");
// Write the new bout info
fwrite($f, $toWrite);
// Close the -status file
fclose($f);


// from getScores.php
$f = fopen("comps/$competitionId/$filename", "a");
// Write one bout's results
fwrite($f, $toWrite);
// fwrite($f, "boutScores[" . $currFencer2 . "][" . $currFencer1 . "] = " . $fencer2Num . ";\r\n") ; // Close the text file
fclose($f);


Expected result:
----------------
// from getBout.php, e.g.

// Bout 2
currBout=2; currFencer1 = 3;  currFencer2 = 4;



// from getResults.php, e.g.

///////////////////////////////////////////////////
// Bout 1
currBout=1; boutStartTimes[1] = '2015-10-12T07:47:58.401Z';
currFencer1 = 1;  currFencer2 = 2;
boutStarted[1][2] = true ; boutStarted[2][1] = true ;
boutScores[1][2] = 3;  boutScores[2][1] = 0;



// from getScores.php, e.g.

///////////////////////////////////////////////////
///////////////////////////////////////////////////
// Bout 1 over 
///////////////////////////////////////////////////
currBout=1; boutStartTimes[1] = '2015-10-12T07:47:58.401Z';
currFencer1 = 1;  currFencer2 = 2;
boutScores[1][2] = 10;  boutScores[2][1] = 0;
boutVictors[1][2] = 'V';   boutVictors[2][1] = 'L';
boutStarted[1][2] = true ; boutStarted[2][1] = true ;
boutStartTimes[1] = '2015-10-12T07:47:58.401Z';
boutFinishTimes[1] = '2015-10-12T07:48:01.587Z';
///////////       ///////////////       ///////////


// from an earlier version  e.g.

currBout=1; boutStartTimes[1] = '2015-10-12T07:47:58.401Z';


Actual result:
--------------
// from an earlier version  e.g.

7:58.401Z';



// 37 characters missing from the intended string, in 0.03% of cases

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-10-13 01:20 UTC] requinix@php.net
-Status: Open +Status: Not a bug -Package: Other web server +Package: Filesystem function related
 [2015-10-13 01:20 UTC] requinix@php.net
Option a) Use file_put_contents() with the append flag. That is atomic.

Option b) Use file locking to prevent multiple instances of PHP from writing at the same time.

A couple links to get you started:
https://en.wikipedia.org/wiki/File_locking
http://php.net/manual/en/function.flock.php

And this reply wouldn't be complete without an obligatory

Option C) Use a transactional database system instead of flat files.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sun Jul 06 20:01:35 2025 UTC