Problems with JSON + PHP

Asked

Viewed 118 times

1

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

Format required:

{"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}");
}

2 answers

2


I believe this occurs when Dexes cease to be sequential, so it is necessary to be an object to continue with the same Dexes.

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]}, why the 5 is the ultimate value, so it still remains 0 until 4.

However, if you remove anyone 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 (existing value 0 and 2 until 5), so it will result {"favoritesIndex":{"0":28,"2":133,"3":38,"4":12,"5":27}}, due to the lack of 1, that was removed.


Then you need to recreate the PHP array, so that it is always in order, without any gap, this can be done as follows:

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

In case there would be any next to that:

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 (how to use array with the json_decode(..., true), the value is reported as a parameter in the function...), this was done only so that it could test faster, as you can see here working.

1

It is putting a natural input in the array, and you are trying to access a key that is not 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 by making the Intel your own value:

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

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

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

  • Yes, the position has to be sequential because several values will be included in the array dynamically, and can you explain to me more about making the index its own value? I tested your excerpt, and it showed a positioning error.

  • If you need this: {"favoritesIndex":[28,22,133,38,12,27]}, and these numbers are the ID., you need to put the ids as keys one level above favoritesIndex, like in the example, to sequence, you will not have these keys, you will have the example you said you have now. What error does it point to ?

  • Undefined offset: 28

  • See if it is building right, give a var_dump() in the array of the favorite object Index and see if it is in the correct format

  • This Undefined offset: 28 error comes from the foreach of the second way, is it ? because it doesn’t find the $key in favoritesIndex

  • No, it is generated by $Settings->favoritesIndex[$ID];

  • Tell me something so I understand, $Settings->favoriteIndex would be a method ? Is this within a class ? if you don’t need the instance, you save to an object-free array $Settings[$ID], and pass this array to write() since the key will always be favoriteIndex, or $Settings['favoriteIndex'][$ID]

  • //includes the json content in the variable $Settings = read(); //$Settings->Indice json $Settings->favoritesIndex[] = x; //rewrite the json in the file $Settings = write($Settings);

  • If you keep a key open '[ ]', without exception, it will sequence, and your answer will be something like {"Indice":{"1":"value 1", "2":"value 2"}}, you need to make $ID go inside [ ], so you have: {"Indice":{"value 1", "value 2"}}, you got it ? you’re just missing the place of the key, you can rewrite with array, you don’t need that object opened in write, call straight, $array['favoriteIndex'][$ID], but if you’re inside a class, it changes a bit

  • Dude, by defining the key as sequential, I’m saying I want this value to always be added as a new index!

  • This {"Indice":{"1":"value 1", "2":"value 2"}} would be defining the array as an object, which for me is not useful

  • Dude, the problem is in the unset in the removeFavorite function()

  • Got it now, just say one more thing and I’ll know what the problem is, do a var_dump($Settings) after read in the first method 'setFavorite' and also in the second 'removeFavorite', and put the answer here, now that I think I understand, I think the error ta in this access '->' because you have already given the code, you can access with $Settings['favoritesIndex'], then yes you will get this answer you want, only responds this var_dump here and we will already know if it is this same

  • Function removeFavorite() { $Settings = read(); foreach($Settings->favoritesIndex AS $key => $value) { if($_REQUEST['id'] == $value) unset($Settings->favoritesIndex[$key]); } $Settings->favoritesIndex = array_values($Settings->favoritesIndex); write($Settings); }

  • What is this? I need the answer of var_dump($Settings), to know how it is inside the target to help you, not the method itself

  • Already solved, the problem was in function removeFavorite.

  • Thanks for the Help!

  • Ah , I understood that you had posted a wrong comment up there kk blzz, put the solution in an answer, I think it is a doubt that more people can have

Show 13 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.