Problems with JSON + PHP

0

I have a JSON file that is being used to store settings, and a php file, which reads and populates the file according to the reported data, however after the settings are often edited by the JSON is has its format changed from Array to Object :

Required format:

{"favoritesIndex":[28,22,133,38,12,27]}

Generated format:

{"favoritesIndex":{"1":28,"2":22,"3":133,"4":38,"5":12,"6":27}}

PHP code:

function read() {return json_decode(file_get_contents('sec_settings/datatable.json'));}
function write($data){return file_put_contents('sec_settings/datatable.json',json_encode($data));}

function setFavorite()
{
    $settings = read();
    $settings->favoritesIndex[] = (int) $_REQUEST['id'];
    $settings = write($settings);
}

function removeFavorite()
{
    $settings = read();

    foreach($settings->favoritesIndex AS $key => $value)
        if($_REQUEST['id'] == $value)
            unset($settings->favoritesIndex[$key]);

    $settings = write($settings);
}

try
{
    if(isset($_REQUEST['fn'])) $_REQUEST['fn']();
}
catch(Exception $e)
{
    die("Could not process requested operation, {$e}");
}
    
asked by anonymous 28.09.2017 / 20:10

2 answers

1

I believe this happens when indexes are no longer sequential, so you need to be an object to continue with the same indexes.

For example, consider this:

$json = json_decode('{"favoritesIndex":[28,22,133,38,12,27]}');

unset($json->favoritesIndex[5]);

echo json_encode($json);

The return will be {"favoritesIndex":[28,22,133,38,12]} , because 5 is the last value, so it still remains from 0 to 4 .

However, if you remove any, other than the last:

$json = json_decode('{"favoritesIndex":[28,22,133,38,12,27]}');

unset($json->favoritesIndex[1]); // Remover o 22, o segundo valor

echo json_encode($json);

You will create a gap (with 0 value and 2 to 5 ), thus resulting in {"favoritesIndex":{"0":28,"2":133,"3":38,"4":12,"5":27}} , due to the lack of 1 , which was removed.

So you have to re-create the PHP array, so that it's always in order, with no gap, this can be done as follows:

$settings['favoritesIndex'] = array_values($settings['favoritesIndex']);

In case there would be any next to it:

function read() {return json_decode(file_get_contents('sec_settings/datatable.json'), true);}
function write($data){return file_put_contents('sec_settings/datatable.json',json_encode($data));}


function setFavorite(int $valor)
{
    $settings = read();
    $settings['favoritesIndex'][] = $valor;
    $settings = write($settings);
}

function removeFavorite(int $valor)
{
    $settings = read();

    $achado = array_search($valor, $settings['favoritesIndex']);
    if($achado !== false){
        unset($settings['favoritesIndex'][$achado]);
    }

    $settings['favoritesIndex'] = array_values($settings['favoritesIndex']);

    $settings = write($settings);
}

Note that there are changes (such as using array with json_decode(..., true) , value is reported as a parameter in function ...), this was done only so you could test faster, As you can see here working .

    
28.09.2017 / 23:36
1

It's putting a natural index on the array, and you're trying to access a key that is not a key, wrong method:

function setFavorite()
{
    $settings = read();
    //Essa abertura [] indica para preencher o indice de acordo com o loop e gera uma chave sequencial
    $settings->favoritesIndex[] = (int) $_REQUEST['id'];
    $settings = write($settings);
}

Do this, making the index the value itself:

function setFavorite()
{
    $settings = read();
    $ID = (int) $_REQUEST['id'];

    $settings->favoritesIndex[$ID];
    $settings = write($settings);
}

I think this will solve, only the positions in the array construction are wrong.

    
28.09.2017 / 20:14