Eduardo Fuentes
Eduardo Fuentes

Reputation: 43

Delete object from json file with PHP

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.

Upvotes: 2

Views: 307

Answers (1)

csb
csb

Reputation: 764

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.

Upvotes: 3

Related Questions