Michael Heneghan Michael Heneghan - 7 months ago 22
PHP Question

How to update a value in a JSON file using PHP

I'm trying to update a value of one of the objects in a json file. The problem is there are several siblings in the same json file with the same key-value pairs.

My Json file looks like so:

{"LogIns":[
{"Username":"Alfred",
"password":"123",
"Won":0,"Lost":0},
{"Username":"Farrah",
"password":"123",
"Won":0,"Lost":0}]}


Each time somebody wins a hand (it's a card game) I need to update the number of games won or lost.

This is the AJAX call to the PHP file:




AJAX:

var username = localStorage.getItem("username");

if(document.getElementById(btnId).value == answer){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange=function() {
console.log("returned:", xhttp.responseText);
}
xhttp.open("POST", "leaderboard.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("username=" + username + "&won=1");

}
else{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange=function() {
console.log(xhttp.responseText);
}
xhttp.open("POST", "leaderboard.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("username=" + username + "&lost=1");

}
setTimeout(reloadPage, 2000);

}


You can take my word for it that the HTML is all correct and is not really needed here, but my PHP file looks like so:

PHP:

<?php

$username = $_POST['username'];

if(isset($_POST['won'])){
$won = $_POST['won'];
//echo $won;
}

if(isset($_POST['lost'])){
$lost = $_POST['lost'];
//echo $lost;
}
$str = file_get_contents('logins.json'); // Save contents of file into a variable

$json = json_decode($str, true); // decode the data and set it to recieve data asynchronosly - store in $json

foreach($json['LogIns'] as $res){
if($res['Username']==$username){
if(isset($won)){
$add = $res['Won'];
$add = ($add + $won);
$res['Won'] = $add;
echo $res['Won'];
}
else{

$add = $res['Lost'];
$add = ($add + $lost);
$res['Lost'] = $add;
echo $res['Lost'];

}
break;
}
}

file_put_contents('logins.json', json_encode($json));

?>


The
xhttp.responseText
that is printed to the screen is always ("1"), but when I print_r $json the won or lost field is still 0.

Does anybody know what i'm doing wrong?

Any help as ever would be greatly appreciated.

Thanks

Answer

Shortly: you are updating a temporary item $res that is NOT referencing the original array element. In PHP, only objects are passed by reference by default. If you want to pass another variable type by reference, you have to prepend & to it.

Some more details here: http://php.net/manual/en/control-structures.foreach.php

Quick fix, untested:

foreach ($json['LogIns'] as $index => $res) {
    if ($res['Username'] == $username) {
        if (isset($won)) {
            $add = $res['Won'];
            $add = ($add + $won);
            $json[$index]['Won'] = $add; // <-
            echo $res['Won']; 
        }
        else{

            $add = $res['Lost'];
            $add = ($add + $lost);
            $json[$index]['Lost'] = $add; // <-
            echo $res['Lost']; 
        }
        break;
    }
}

Or you can pass the array item to the loop by reference:

foreach ($json['LogIns'] as &$res) { // <-
    if ($res['Username'] == $username) {
        if (isset($won)) {
            $add = $res['Won'];
            $add = ($add + $won);
            $res['Won'] = $add;
            echo $res['Won']; 
        }
        else{

            $add = $res['Lost'];
            $add = ($add + $lost);
            $res['Lost'] = $add;
            echo $res['Lost']; 
        }
        break;
    }
}
Comments