Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Shiva's avatar
Level 5

Deleting from a json file

I have a json file that looks like this

    {
        "product_1": {
            "category_1": "Category 1",
            "category_2": "Category 2"
        },
    }

What I'm trying to do is when I delete a category I want to remove the "key":"value" from the json file.

Here is my code

    public function deleteCategory($product, $category)
    {
        $storage = storage_path("/products.json");
        $file = file_get_contents($storage);
        $json = json_decode($file);

        unset($json->$product->$category);

        file_put_contents($storage, json_encode($json, JSON_PRETTY_PRINT));

        return (array)$json;
    }

What happens is when I delete a category it doesn't remove it from the json.

And what I found strange was if I did this dd(file_put_contents($storage, json_encode($json, JSON_PRETTY_PRINT))) then it would work but if I only had file_put_contents($storage, json_encode($json, JSON_PRETTY_PRINT)) then it doesn't work. So I'm not sure where I'm going wrong.

0 likes
8 replies
automica's avatar

@shiva I've Just dropped the block of code you posted into a vanilla Laravel 8 install and have different results to you.

my products.json file:

{
    "product_1": {
        "category_1": "Category 1",
        "category_2": "Category 2"
    }
}

same as yours

I've hard coded my $product & $category so I could do it inline:

    $product = 'product_1';
    $category = 'category_1';


        $storage = storage_path("/products.json");
        $file = file_get_contents($storage);
        $object = json_decode($file); // renamed $json to $object as its no longer json at this point

        unset($object->$product->$category);

        file_put_contents($storage, json_encode($object, JSON_PRETTY_PRINT));

        return (array)$object;

returns

{
    "product_1": {
        "category_2": "Category 2"
    }
}

nothing wrong with the code it seems, which points to your json being invalid.

if you exclude JSON_PRETTY_PRINT you still get valid json, so not necessary.

I'd also add some error checking to only delete category if its set.

    $product = 'product_1';
    $category = 'category_1';
    
    /**
     * @param string $product
     * @param string $category
     * @return array
     */
    public function deleteCategory(string $product, string $category): array
    {
        $storage = storage_path("/products.json");
        $file = file_get_contents($storage);
        $object = json_decode($file);

        if (!isset($object->$product->$category)) {
            throw new \Exception('cant delete');
        }

        unset($object->$product->$category);

        file_put_contents($storage, json_encode($object));

        return (array)$object;
    }

or if you want to use an associative array instead

    $product = 'product_1';
    $category = 'category_1';
    
    /**
     * @param string $product
     * @param string $category
     * @return array
     */
    public function deleteCategory(string $product, string $category): array
    {
        $storage = storage_path("/products.json");
        $file = file_get_contents($storage);
        $data = json_decode($file, true);

        if (!isset($data['product']['category'])) {
            throw new \Exception('product category does not exist');
        }

        unset($data[$product][$category]);

        file_put_contents($storage, json_encode($data));

        return $data;
    }
laracoft's avatar

@shiva Easier to delete using an associative array

public function deleteCategory($product, $category)
{
    $storage = storage_path("/products.json");
    $file = file_get_contents($storage);
    $json = json_decode($file, true);

    unset($json[$product][$category]);

    file_put_contents($storage, json_encode($json, JSON_PRETTY_PRINT));

    return (array)$json;
}
automica's avatar

@laracoft you still need to check you've got the key before deleting

if(!isset($json[$product][$category])){
 throw new \Exception('cant delete');
}

also, as above, when you do this:

  $json = json_decode($file, true);

the variable isn't json any more. In your case its an array so should be named as such. it would be better described as what the data represents, not the its type. eg $data or $products.

laracoft's avatar

@automica thanks, I have made the necessary changes.

public function deleteCategory($product, $category)
{
    $storage = storage_path("/products.json");
    $file = file_get_contents($storage);
    $array = json_decode($file, true);

    if(!isset($array[$product][$category])){
        throw new \Exception("Can't delete non-exists [$product][$category]");
    }
    
    unset($array[$product][$category]);

    file_put_contents($storage, json_encode($array, JSON_PRETTY_PRINT));

    return (array)$array;
}
automica's avatar

@laracoft you don't need the else here either:

    if(!isset($array[$product][$category])){
        throw new \Exception("Can't delete non-exists [$product][$category]");
    }
    else
    {
        unset($array[$product][$category]);
    }

if it throws an exception its not going to execute any more code.

hence why I did

    if(!isset($array[$product][$category])){
        throw new \Exception("Can't delete non-exists [$product][$category]");
    }

    unset($array[$product][$category]);

Please or to participate in this conversation.