2

Well, I have a web project and I have to be saving things temporarily, I started work with a json file, so far I can add and update. The json file looks like this:

[
  {
    "username": "Baldwin",
    "products": [
      {
        "id": 0,
        "amount": 10
      },
      {
        "id": 1,
        "amount": 9
      },
      {
        "id": 2,
        "amount": 9
      }
    ]
  },
  {
    "username": "Alice",
    "products": [
      {
        "id": 0,
        "amount": 11
      },
      {
        "id": 1,
        "amount": 13
      },
      {
        "id": 2,
        "amount": 6
      }
    ]
  },
  {
    "username": "Terry",
    "products": [
      {
        "id": 0,
        "amount": 12
      },
      {
        "id": 1,
        "amount": 14
      },
      {
        "id": 2,
        "amount": 5
      }
    ]
  }
]

The problem comes when I want to delete an specific array or when I want to delete it completely, I can do it and it works fine, but I have the doubt about why when I delete the object, other fields are add to the json file, like an id.

When i delete just one product inside of the "products" array something like this happen:

[
  {
    "username": "Baldwin",
    "products": { "1": { "id": 1, "amount": 9 }, "2": { "id": 2, "amount": 9 } }
  },
  {
    "username": "Alice",
    "products": [
      { "id": 0, "amount": 11 },
      { "id": 1, "amount": 13 },
      { "id": 2, "amount": 6 }
    ]
  },
  {
    "username": "Terry",
    "products": [
      { "id": 0, "amount": 12 },
      { "id": 1, "amount": 14 },
      { "id": 2, "amount": 5 }
    ]
  }
]

And when i delete a complete array from the json file, something like this happen:

{
  "1": {
    "username": "Alice",
    "products": [
      { "id": 0, "amount": 11 },
      { "id": 1, "amount": 13 },
      { "id": 2, "amount": 6 }
    ]
  },
  "2": {
    "username": "Terry",
    "products": [
      { "id": 0, "amount": 12 },
      { "id": 1, "amount": 14 },
      { "id": 2, "amount": 5 }
    ]
  }
}

My php file to delete:

<?php 

    // load file
    $data = file_get_contents('results.json');

    // decode json to associative array
    $json_arr = json_decode($data, true);

    $flag = false;
    // We check if the user wants to delete all or just one product
    if(isset($_POST["all"])):

        $username = $_POST["username"];

        foreach ($json_arr as $key => $value):

            // find the username on the json file
            if($value["username"] == $username):

                unset($json_arr[$key]);
                break;

            endif;

        endforeach; 

    elseif(isset($_POST["one"])):

        $username = $_POST["username"];
        $id = $_POST["id"];

        foreach ($json_arr as $key => $value):

            // find the username on the json file
            if($value["username"] == $username):

                // loop products of the current username
                foreach ($json_arr[$key]["products"] as $k => $product):

                    // find the id of the product 
                    if($json_arr[$key]["products"][$k]["id"] == (int)$id):

                        // delete the product
                        unset($json_arr[$key]["products"][$k]);

                    endif;

                endforeach;

            endif;

        endforeach; 

    endif;

     // encode json and save to file
    file_put_contents('results.json', json_encode($json_arr));

    // redirect to show.php
    header("Location: show.php");
?>

I've been taking a look to questions like this one but i couldn't find something with php, i would like to know how to solve this or if this is normal.

rob006
  • 21,383
  • 5
  • 53
  • 74
Eduardo Fuentes
  • 43
  • 1
  • 2
  • 10

1 Answers1

3

What happens when you use unset($json_arr[0]) is that the first element is removed, but the keys are not updated. If you inspect the array after the removal, you'll find that your array has two elements, at $json_arr[1] and $json_arr[2].

When you then perform a json_encode($json_arr) on this, PHP's JSON decoder looks at the array and since arrays are supposed to begin at the 0th element but this array begins at 1, it decides that in order to preserve the keys, the array would have to be converted to an associative array - which transforms the integer array keys into string keys in JSON.

For a short and quick solution, you can try:

$json_arr = array_diff($json_arr, [$key]);

You could even use array_splice or array_values - see here for inspiration.

csb
  • 674
  • 5
  • 13
  • I get it, but still, i tried with the code and that throw me an error: Notice: Array to string conversion in line 21 that is where i put the line of code. – Eduardo Fuentes Apr 27 '18 at 02:18
  • I was going to say that maybe you were using `$key` instead of `[$key]`. But I'm glad it works for you now. In any case, the relevant lines of code should've been replaced with `$json_arr = array_diff($json_arr, [$key]);` and `$json_arr = array_diff($json_arr[$key]["products"], [$k]);` respectively. – csb Apr 27 '18 at 02:26
  • Oh yeah, i was using `$key` instead of `[$key]`, that solve the problem as well. Thanks!! – Eduardo Fuentes Apr 27 '18 at 02:33