Leandro
Leandro

Reputation: 23

Problem with json_encode() it removes the "0" key from JSON string number in PHP

I need to call this value registered in a MySQL column:

{"0":[{"Type":3,"Seconds":-185}],"1":[{"Type":4,"Seconds":-144}]}

With this form I get the JSON from the MySQL database:

$boosterResultant = $mysqli->query('SELECT boosters FROM player_equipment WHERE userId = '.$player['userId'].'')->fetch_assoc()['boosters']; //response: "{\"0\":[{\"Type\":3,\"Seconds\":-185}],\"1\":[{\"Type\":4,\"Seconds\":-144}]}"

I want to access what is in 'Seconds' to modify its value, so I use this form to modify it:

$boosterFinal = json_decode($boosterResultant,true);
$boosterFinal[0][0]['Seconds'] += 36000; //the value is changed successfully
echo "Output:", json_encode($boosterFinal); //out: [[{"Type":3,"Seconds":35815}],[{"Type":4,"Seconds":-144}]]

Since I run $boosterFinal = json_decode($boosterResultant,true); I get this: [[{"Type":3,"Seconds":-185}],[{"Type":4,"Seconds":-144}]] but I need to stay like this for update later in the DB:

{"0":[{"Type":3,"Seconds":35815}],"1":[{"Type":4,"Seconds":-144}]} //good
//bad: [[{"Type":3,"Seconds":35815}],[{"Type":4,"Seconds":-144}]]

Edit: Thanks to @A. Cedano (link of answer in Spanish forum: here), I found the answer:

//This is the data that comes from the sample DB
$str='{"0":[{"Type":3,"Seconds":-185}],"1":[{"Type":4,"Seconds":-144}]}';
//Don't pass TRUE to json_decode to work as JSON as is
$mJson=json_decode($str);
$mJson->{0}[0]->Seconds+=36000;
//Object Test
echo $mJson; //Output: {"0":[{"Type":3,"Seconds":35815}],"1":[{"Type":4,"Seconds":-144}]}

Upvotes: 2

Views: 1447

Answers (2)

Hef
Hef

Reputation: 1430

I had a similar problem, where JSON_FORCE_OBJECT didn't work. I had an array that looked like this:

<?php
$array = [
    "someKey" => [
        0 => "Some text....",
        1 => "Some other text....."
    ]
];

Using json_encode with no flags I got a JSON object that looked like this:

{
    "someKey": [
        ["Some text...."],
        {"1": "Some other text....."}
    ]
}

This is clearly not what I had as the PHP object, and not what I want as the JSON object.

with the JSON_FORCE_OBJECT I got a JSON object that looked like this:

{
    "someKey": [
        {"0": "Some text...."},
        {"1": "Some other text....."}
    ]
}

Which does fix the issuse I had, but causes another issue. It would add unnecessary keys to arrays that don't have keys. Like this:

$array = ["Sometext..."];
echo json_encode($array, JSON_PRETTY_PRINT|JSON_FORCE_OBJECT);
// {0: "Sometext..."}

We once again have the same issue, that the JSON object is not the same as the original PHP array.

Solution:

I used stdClass for the array that had numeric keys. and It encoded it to JSON correctly. code:

$array = [];

$stdClass = new stdClass();

$stdClass->{0} = "Some text...";
$stdClass->{1} = "Some other text....";

array_push($array, ["someKey" => $stdClass]);

$json = json_encode($array, JSON_PRETTY_PRINT);

echo $json;

//Output:
/*
{
    "someKey": [
        {"0": "Some text...."},
        {"1": "Some other text....."}
    ]
}
*/

This is because PHP does not touch the indexes when encoding an stdClass.

Upvotes: 0

Erty Seidohl
Erty Seidohl

Reputation: 4559

If PHP sees that your array keys are ascending ints, it automatically converts them into an array (php.net/manual/en/function.json-encode.php)

You can disable this by passing the JSON_FORCE_OBJECT flag as a second param into json_encode: json_encode($boosterFinal, JSON_FORCE_OBJECT)

Upvotes: 4

Related Questions