2

I'm currently trying to use file_put_contents to update a JSON file of mine. This is what my PHP currently looks like:

$result = file_put_contents('Resources/logs/file.json', $newJsonString);
if($result === true) {
    echo "true";
} else {
    echo "false";
}

However, it always returns false. Nevertheless, I have set the directory permissions to 777 for BOTH Resources and logs. I have also set file permissions to 777 for file.json.

The path is also correct, as file_get_contents works with the same path from the same file.

To further prove my point, I have also ran sudo chown -R www-data:www-data /var/www/html/core/Resources/ to give permission to the directory Resources (and everything within) to be written to by the user www-data (which I'm assuming would allow the JSON file to be written to by running the PHP script online).

I don't know if this would be helpful, but I'm also running this PHP script by sending POST data to it via JavaScript from a different server/website.

Why in the world is file_put_contents STILL returning false and not writing to the file? It always makes the JSON file blank after it is ran.

Supplementary Code:

This is the whole chunk of code, including the file_put_contents section:

$jsonString = file_get_contents('Resources/logs/file.json');
$data = json_decode($jsonString);
$data->coins = $data->coins + $coins;
$data->uses = $data->uses + 1;
print_r($data);
$newJsonString = json_encode($data);
$result = file_put_contents('Resources/logs/file.json', $newJsonString);
if($result === true) {
    echo "true";
} else {
    echo "false";
}

...and this is the JSON file:

{"coins":"0","uses":"0"}

Any help would be highly appreciated, I've been trying to fix this issue for one whole day already.

Edit 1:

I forgot to mention this, but this code was working perfectly fine yesterday for about an hour. Then all of a sudden it stopped working and started making the JSON file blank.

Edit 2:

I have just cleared the Apache error log, and the script it working again (which is good). However, file_put_contents is still returning false. What is going on...

Edit 3:

Thanks to Laurent Wartel I have updated my if statement for file_put_contents and it seems like it is no longer returning false.

if($result === false) {
    echo "Error";
} else {
    echo "All good, $result bytes written";
}
user3681788
  • 221
  • 4
  • 15
  • Take a look in the server error log. Notwithstanding what you've done to release the permissions, that's still the probable cause. The error log will tell you if that's the case. –  Jul 22 '14 at 09:51
  • Which user is running the PHP process? Probably www-data runs just the HTTP server but not the PHP process. – TiMESPLiNTER Jul 22 '14 at 09:51
  • @MikeW How can I do that? I'm still extremely new to this realm of server work. – user3681788 Jul 22 '14 at 09:54
  • @TiMESPLiNTER How can I check that? – user3681788 Jul 22 '14 at 09:54
  • @user3681788 try this: http://stackoverflow.com/a/7771601/1652031 – TiMESPLiNTER Jul 22 '14 at 10:01
  • The log files are in `/etc/httpd/logs`, or possibly `/var/www/log`. –  Jul 22 '14 at 10:02
  • @TiMESPLiNTER The user `www-data` is running the PHP process. However, I have just cleared the Apache error log, and the script is working again. Any idea on why this is happening? – user3681788 Jul 22 '14 at 10:09

3 Answers3

1

Try to write a string to your file. This way you can determine if your problem resides on the file writing or the content generation:

file_put_contents('Resources/logs/file.json', 'Hello, file');

Also, I'd add a LOCK_EX flag to the file write call to make sure you are not running into concurrency issues.

NiloVelez
  • 3,611
  • 1
  • 22
  • 30
  • As of right now, my code is once again working. However, can you further elaborate on `LOCK_EX` and show an example of how it can be used? By concurrency do you mean multiple people using it at once? – user3681788 Jul 22 '14 at 10:27
  • Also, as shown here, does `LOCK_EX` need to be used with `FILE_APPEND`? Because in my code I'm not appending anything, but replacing. http://stackoverflow.com/questions/5479580/is-there-a-risk-in-running-file-put-contents-on-the-same-file-from-different-p#answer-5479596 – user3681788 Jul 22 '14 at 10:31
  • LOCK_EX is one of the flags you can add when writing to a file. It can be use along with FILE_APPEND, but it is no necessary. Your write call will look like this: file_put_contents('Resources/logs/file.json', $newJsonString, LOCK_EX); This ensures that you get an error if you try to write to a file that is already been written to. – NiloVelez Jul 22 '14 at 10:38
  • Ahh, thank you. And let's say that I do not use the `LOCK_EX` flag, what issues would concurrency provoke? Could that lead to issues like blank files and such? – user3681788 Jul 22 '14 at 10:43
  • It can cause intermittent file write errors quite difficult to debug. I think your problem is that sometimes you are reading the file while it is still being written, trying to json_decode it (I'd also look for errors there), and writting the results (that might be blank) to file. – NiloVelez Jul 22 '14 at 19:04
0

From the doc PHP: file_put_contents - Manual

This function returns the number of bytes that were written to the file, or FALSE on failure. Warning

This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.

Modify your code...

if($result === false) {
    echo "Error";
} else {
    echo "All good, $result bytes written";
}
Laurent W.
  • 3,629
  • 2
  • 20
  • 29
0

http://php.net/manual/en/function.file-put-contents.php

This function returns the number of bytes that were written to the file, or FALSE on failure.

You can't user the identical comparison operator to check for success. Both of this alternatives are valid:

if($result) {
    echo "true";
} else {
    echo "false";
}

or

if($result === false) {
    echo "false";
} else {
    echo "true";
}
NiloVelez
  • 3,611
  • 1
  • 22
  • 30