0

I am having trouble getting these arrays to nest properly. I am grabbing all the rows from a SQL database and building an array to output in JSON for my crud app. One category has been easy, but the client now wants subcategories and that's when I hit a major wall. I am trying to nest these subcategories into categories. I can do either, but am failing to get them working together. The following is my PHP code:

while ($row = $query->fetch_assoc()) {
    $categories[$row['category']][] = array(
        $row['subcategory'] => $subcategories[$row['subcategory']][] = array(
            'id'                 => $row['id'],
            'item_name'          => $row['item_name'],
            'description'        => $row['description'],
            'price'              => $row['price'],
        ),
    );
}

foreach ($categories as $key => $value) {
    $category_data[] = array(
        'category'   => $key,
        'category_list' => $value,
    );
}

foreach ($subcategories as $key => $value) {
    $subcategory_data[] = array(
        'subcategory'   => $key,
        'subcategory_list' => $value,
    );
}

When I json_encode($category_data) I get the following JSON:

[
{
    "category": "Beer",
    "category_list": [
        {
            "Draft Beer": {
                "id": "1",
                "item_name": "Yuengling",
                "description": "Lager. Pottstown, Pa. An American classic."
            }
        },
        {
            "Draft Beer": {
                "id": "6",
                "item_name": "Bud Light",
                "description": "American Light Lager"
            }
        },
        {
            "Domestic Bottles": {
                "id": "9",
                "item_name": "Stone IPA",
                "description": "India Pale Ale.<em> Escondido, Colo."
            }
        }
    ]
},
{
    "category": "Wine",
    "category_list": [...]
}
]

Which might work, but I would like it to join the like keys (ie: Draft Beer) into the same array. It does do that when I json_encode($subcategory_data) as shown below, but its not separated into categories, just the subcategories.

[
{
    "subcategory": "Draft Beer",
    "subcategory_list": [
        {
            "id": "1",
            "item_name": "Yuengling",
            "description": "Lager. Pottstown, Pa."
        },
        {
            "id": "6",
            "item_name": "Bud Light",
            "description": "American Light Lager. Milwaukee, Wisc."
        }
    ]
},
{
    "subcategory": "Red Wine",
    "subcategory_list": [
        {
            "id": "17",
            "item_name": "Kendall-Jackson",
            "description": "Cabernet Sauvignon, 2010."
        },
        {
            "id": "18",
            "item_name": "Sanford",
            "description": "Pinot Noir, 2011. Lompoc, Calif"
        }
    ]
},
{
    "subcategory": "Domestic Bottles",
    "subcategory_list": [
        {
            "id": "9",
            "item_name": "Stone IPA",
            "description": "India Pale Ale. Escondido, Colo."
        },
        {
            "id": "10",
            "item_name": "Blue Moon",
            "description": "Belgian-style Wheat Ale."
        }
    ]
}
]

So my question is why does it merge in the second set of data but not the first. How do I get the subcategory_data into the category_data. Any help id truly appreciated. Below is an example if what I am looking for:

{
    "category_name":"Beer",
    "category_list" : [
        {
            "subcategory_name": "Draft Beer",
            "subcategory_list": [
            {
                "id": "1",
                "item_name": "Yuengling",
                "description": "Lager. Pottstown, Pa."
            },
            {
                "id": "6",
                "item_name": "Bud Light",
                "description": "American Light Lager. Milwaukee, Wisc."
            }
        }
    ]   
},
{
    "category_name":"Wine",
    "category_list" : [
        {
            "subcategory_name": "Red Wine",
            "subcategory_list": [...]
        }
    ]
}

Thanks for looking, I am fairly new to PHP and am relying on my javascript skills.

1 Answer 1

1

First, try var_dump($categories). You'll see that you're building a rather weird data structure (you have arrays of 1-element arrays...). The following code will build a simpler structure:

$categories[$row['category']][$row['subcategory']][] = array(
  'id'                 => $row['id'],
  'item_name'          => $row['item_name'],
  'description'        => $row['description'],
  'price'              => $row['price'],
  );

This will serialize to JSON that's probably acceptable as is:

{
  "Beer": {
    "Draft Beer": [
      {
        "id": "1",
        "item_name": "Yuengling",
        "description": "Lager. Pottstown, Pa."
      },
      {
        "id": "6",
        "item_name": "Bud Light",
        "description": "American Light Lager. Milwaukee, Wisc."
      }
    ],
    ...

An additional transformation gets the data in the format you asked for:

foreach ($categories as $category_name => $subcategories) {
  $subcategory_data = array();
  foreach ($subcategories as $subcategory_name => $items) {
    $subcategory_data[] = array(
      'subcategory_name' => $subcategory_name,
      'subcategory_list' => $items
      );
  }
  $category_data[] = array(
    'category_name' => $category_name,
    'category_items' => $subcategory_data
    );                 
}
Sign up to request clarification or add additional context in comments.

1 Comment

Wow, this works like a charm! I know the structure is crazy but it has to be since I wont know the names of new categories, and subcategories down the road. I had a hunch it you could do 2 foreach in there, but it just got out of hand and I didn't really know which direction to go. Thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.