php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72983 file_put_contents does not overwrite if file exists
Submitted: 2016-08-31 03:00 UTC Modified: 2016-09-05 05:36 UTC
From: jim dot michaels at Jesusnjim dot com Assigned: cmb (profile)
Status: Not a bug Package: Filesystem function related
PHP Version: 7.1.0beta3 OS: vista x32 amd
Private report: No CVE-ID: None
 [2016-08-31 03:00 UTC] jim dot michaels at Jesusnjim dot com
Description:
------------
file_put_contents() does not overwrite if file exists. if file exists, file is not touched. if file is open in programmer's editor, rw.txt file does not refresh. this could be related with c++ old gcc bug in fstream's std::ios_base::creat notworking for while a number of years.


Test script:
---------------
<?php
$a=file_get_contents("\\w\\Jesusnjim\\menu7a.xml");
$a=preg_replace('/\//','\\',$a);
file_put_contents("\\w\\Jesusnjim\\rw.txt", $a);
?>

2nd time:
<?php
$a=file_get_contents("\\w\\Jesusnjim\\menu7a.xml");
$a=preg_replace('/\//','\\\\',$a);
file_put_contents("\\w\\Jesusnjim\\rw.txt", $a);
?>

Expected result:
----------------
expected / to be changed to \\ and for rw.txt to be changed in programmer's editor jedit and to be notified that file was changed.

Actual result:
--------------
if file is open in programmer's editor, rw.txt file does not refresh.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-08-31 16:24 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2016-08-31 16:24 UTC] cmb@php.net
> if file is open in programmer's editor, rw.txt file does not
> refresh.

Is it possible that this editor locks the file? Please enable
error_reporting=E_ALL, and see if there are any warnings shown.

> this could be related with c++ old gcc bug in fstream's
> std::ios_base::creat notworking for while a number of years.

Did you compile the php.exe binary with GCC? The officially
distributed php.exes are compiled with Visual C++.
 [2016-09-01 10:30 UTC] jmichae3 at yahoo dot com
yes, error reporting was set for E_ALL.
 I cannot compile php. requires languages and utilities I do not have.
I don't have linux.
this is on windows vista.
 [2016-09-02 15:34 UTC] fernando at null-life dot com
Can't reproduce this issue on a Windows 8 with PHP 7.1 Beta 3 from windows.php.net QA

I tried with a local path and with a SMB remote path:

<?php
error_reporting(E_ALL);
file_put_contents('test.txt', "HOLA");
var_dump(file_get_contents('test.txt') == "HOLA");
file_put_contents('test.txt', "ADIOS");
var_dump(file_get_contents('test.txt') == "ADIOS");

file_put_contents('\\\\server\folder\test.txt', "HOLA");
var_dump(file_get_contents('\\\\server\folder\test.txt') == "HOLA");
file_put_contents('\\\\server\folder\test.txt', "ADIOS");
var_dump(file_get_contents('\\\\server\folder\test.txt') == "ADIOS");


D:\fms\php710beta3>php file.php
bool(true)
bool(true)
bool(true)
bool(true)
 [2016-09-02 15:46 UTC] cmb@php.net
Thanks for checking this issue, fernando. I don't know what's
wrong in the OP's case, but I suggest to check the return values
of all three functions.
 [2016-09-03 04:43 UTC] jim dot michaels at Jesusnjim dot com
-Status: Feedback +Status: Assigned
 [2016-09-03 04:43 UTC] jim dot michaels at Jesusnjim dot com
<?php
$a="a / b";
$a=preg_replace('/\//','\\',$a);
echo file_put_contents("rw.txt", $a);
$a=preg_replace('/\//','\\\\',$a);
echo file_put_contents("rw.txt", $a);
?>

outputs 55 and rw.txt contains a \ b which it should not. no it's not open in an editor. create always is not enabled in the interpreter. 2nd write fails to write to file, same as before.
5==strlen($a).
 [2016-09-03 05:45 UTC] requinix@php.net
-Status: Assigned +Status: Not a bug
 [2016-09-03 05:45 UTC] requinix@php.net
'\\\\' is interpreted by PHP to be two backslashes, which are then interpreted by PCRE to be a single escaped backslash.
You need eight - count 'em EIGHT - backslashes to get two in the output.

https://3v4l.org/oLENr
 [2016-09-04 02:28 UTC] jmichae3 at yahoo dot com
you are missing the point. even if I had just written "a" then "b" to the file (which seems to work now for some reason), the file would still not 

that 8 \\\\\\\\\ for 1 \ character is a bell-ringer for a problem that needs fixing. really. I got that down to 4 for 1 it should be 2 when it's in the replace with area shouldn't it?
I would rather use extended POSIX regex than PCRE.

this bug seems to be fixed now (sort of, except for the 8 \ debacle), and I don't remember replacing php.
 [2016-09-04 02:33 UTC] jmichae3 at yahoo dot com
am now using this code.
<?php
$a="a / b\r\n";
echo file_put_contents("rw.txt", $a);
$a=preg_replace('/\//','\\\\', $a);//bug in PCRE doesn't replace / with 2 \ chars 
echo $a;
echo file_put_contents("rw.txt", $a);
system("dir rw.txt");
system("type rw.txt");//should be a \\ b
?>

and this does overwrite like it's supposed to.
 [2016-09-04 02:50 UTC] requinix@php.net
Actually you're the one missing the point. There is no bug. The problem is that your code was not doing what you thought it was doing. It has nothing to do with files and everything to do with you not understanding what was happening with backslashes.

https://3v4l.org/C361B

See how the output in both versions is the same? Writing to the file worked fine, but you were writing the same value both times.

"that 8 \\\\\\\\\ for 1 \ character is a bell-ringer for a problem that needs fixing"

I'm not sure how you managed to misunderstand my comment, but between PHP and PCRE you need two levels of escaping. That's 4x the number of backslashes required. One in the output = 4 in the string, two in the output = 8 in the string.

Side note: here's what happens when you use 1-8 backslashes in PHP and PHP+PCRE: https://3v4l.org/Sjn85

"//bug in PCRE doesn't replace / with 2 \ chars"
No bug. There is exactly one bug in this bug report and it is with your own code. Not with PHP. Not with PCRE.
 [2016-09-04 10:16 UTC] cmb@php.net
> No bug. There is exactly one bug in this bug report and it is
> with your own code. Not with PHP. Not with PCRE.

That.

Suggestion: use str_replace() instead of preg_replace() in this
case:

  str_replace('/', '\\', $a);
 [2016-09-05 03:21 UTC] jmichae3 at yahoo dot com
c:\>php menu7a.php
This version of c:\php71nts\php.exe is not compatible with the version of Windows you're running. Check your computer's system information to see whether y
ou need a x86 (32-bit) or x64 (64-bit) version of the program, and then contact the software publisher.

c:\>

using vista 32, please backrev your compiler.
 [2016-09-05 04:00 UTC] requinix@php.net
Given that you were able to run PHP just fine earlier, what changed? Are you sure you downloaded the x86 build?
 [2016-09-05 05:30 UTC] jim dot michaels at Jesusnjim dot com
why does it seem file_put_contents again does not touch my files? file dates have not changed and menu has not been inserted.

yet when I test locally it "works".. so it works sometimes and fails most of the time. does file_put_contents like \ or / in its filepaths, absolute or relative or both?
 [2016-09-05 05:36 UTC] requinix@php.net
-Block user comment: No +Block user comment: Yes
 [2016-09-05 05:36 UTC] requinix@php.net
Sorry, but your problem does not imply a bug in PHP itself.  For a
list of more appropriate places to ask for help using PHP, please
visit http://www.php.net/support.php as this bug system is not the
appropriate forum for asking support questions.  Due to the volume
of reports we can not explain in detail here why your report is not
a bug.  The support channels will be able to provide an explanation
for you.

Thank you for your interest in PHP.


 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Fri Nov 27 12:01:23 2020 UTC