ryanpitts1
ryanpitts1

Reputation: 894

PHP - Convert an array into a multidimensional json object

I have a query SELECT * FROM NavigationMenu ORDER BY parentNavigationMenuId ASC, navigationOrder ASC that will return an array of nav objects. The result i have to work with looks like this:

array (
  0 => 
  array (
    'navigationMenuId' => '1',
    'parentNavigationMenuId' => '0',
    'fullURL' => '/index',
    'contentSlug' => 'index',
    'contentAlias' => 'Index',
    'navigationAnchor' => 'Home',
    'navigationOrder' => '1',
    'subNavigationItems' => 
    array (
    ),
  ),
  1 => 
  array (
    'navigationMenuId' => '2',
    'parentNavigationMenuId' => '0',
    'fullURL' => '/top-nav-1/index',
    'contentSlug' => 'index',
    'contentAlias' => 'Index',
    'navigationAnchor' => 'Top Nav 1',
    'navigationOrder' => '2',
    'subNavigationItems' => 
    array (
    ),
  ),
  2 => 
  array (
    'navigationMenuId' => '3',
    'parentNavigationMenuId' => '0',
    'fullURL' => '/top-nav-2/index',
    'contentSlug' => 'index',
    'contentAlias' => 'Index',
    'navigationAnchor' => 'Top Nav 2',
    'navigationOrder' => '3',
    'subNavigationItems' => 
    array (
    ),
  ),
  3 => 
  array (
    'navigationMenuId' => '8',
    'parentNavigationMenuId' => '0',
    'fullURL' => '/top-nav-3/index',
    'contentSlug' => 'index',
    'contentAlias' => 'Top Nav 3',
    'navigationAnchor' => 'Top Nav 3',
    'navigationOrder' => '4',
    'subNavigationItems' => 
    array (
    ),
  ),
  4 => 
  array (
    'navigationMenuId' => '9',
    'parentNavigationMenuId' => '0',
    'fullURL' => '/top-nav-4/index',
    'contentSlug' => 'index',
    'contentAlias' => 'Top Nav 4',
    'navigationAnchor' => 'Top Nav 4',
    'navigationOrder' => '5',
    'subNavigationItems' => 
    array (
    ),
  ),
  5 => 
  array (
    'navigationMenuId' => '13',
    'parentNavigationMenuId' => '0',
    'fullURL' => '/top-nav-5/index',
    'contentSlug' => 'index',
    'contentAlias' => 'Top Nav 5',
    'navigationAnchor' => 'Top Nav 5',
    'navigationOrder' => '6',
    'subNavigationItems' => 
    array (
    ),
  ),
  6 => 
  array (
    'navigationMenuId' => '4',
    'parentNavigationMenuId' => '3',
    'fullURL' => '/top-nav-2/sub-nav-1',
    'contentSlug' => 'sub-nav-1',
    'contentAlias' => 'Sub Nav 1',
    'navigationAnchor' => 'Sub Nav 1',
    'navigationOrder' => '1',
    'subNavigationItems' => 
    array (
    ),
  ),
  7 => 
  array (
    'navigationMenuId' => '5',
    'parentNavigationMenuId' => '3',
    'fullURL' => '/top-nav-2/sub-nav-2',
    'contentSlug' => 'sub-nav-2',
    'contentAlias' => 'Sub Nav 2',
    'navigationAnchor' => 'Sub Nav 2',
    'navigationOrder' => '2',
    'subNavigationItems' => 
    array (
    ),
  ),
  8 => 
  array (
    'navigationMenuId' => '6',
    'parentNavigationMenuId' => '3',
    'fullURL' => '/top-nav-2/sub-nav-3',
    'contentSlug' => 'sub-nav-3',
    'contentAlias' => 'Sub Nav 3',
    'navigationAnchor' => 'Sub Nav 3',
    'navigationOrder' => '3',
    'subNavigationItems' => 
    array (
    ),
  ),
  9 => 
  array (
    'navigationMenuId' => '7',
    'parentNavigationMenuId' => '3',
    'fullURL' => '/top-nav-2/sub-nav-4',
    'contentSlug' => 'sub-nav-4',
    'contentAlias' => 'Sub Nav 4',
    'navigationAnchor' => 'Sub Nav 4',
    'navigationOrder' => '4',
    'subNavigationItems' => 
    array (
    ),
  ),
  10 => 
  array (
    'navigationMenuId' => '10',
    'parentNavigationMenuId' => '9',
    'fullURL' => '/top-nav-4/sub-nav-1',
    'contentSlug' => 'sub-nav-1',
    'contentAlias' => 'Sub Nav 1',
    'navigationAnchor' => 'Sub Nav 1',
    'navigationOrder' => '1',
    'subNavigationItems' => 
    array (
    ),
  ),
  11 => 
  array (
    'navigationMenuId' => '11',
    'parentNavigationMenuId' => '9',
    'fullURL' => '/top-nav-4/sub-nav-2',
    'contentSlug' => 'sub-nav-2',
    'contentAlias' => 'Sub Nav 2',
    'navigationAnchor' => 'Sub Nav 2',
    'navigationOrder' => '2',
    'subNavigationItems' => 
    array (
    ),
  ),
  12 => 
  array (
    'navigationMenuId' => '12',
    'parentNavigationMenuId' => '9',
    'fullURL' => '/top-nav-4/sub-nav-3',
    'contentSlug' => 'sub-nav-3',
    'contentAlias' => 'Sub Nav 3',
    'navigationAnchor' => 'Sub Nav 3',
    'navigationOrder' => '3',
    'subNavigationItems' => 
    array (
    ),
  ),
)

Any one of these objects can have child nav items (a child can have other children and so on) which is why each nav item has an empty array of subNavigationItems. I basically want to use the navigationMenuId and parentNavigationMenuId properties and build a json object that has the correct children nested under the correct parents. I'm assuming it could be done with a series of loops for the logic of it is giving me a headache. Anyone have any thoughts on how this can be achieved? Here is an example json of what i would like (or something similar):

    [
        {
            "navigationMenuId": "1",
            "parentNavigationMenuId": "0",
            "fullURL": "/index",
            "contentSlug": "index",
            "contentAlias": "Index",
            "navigationAnchor": "Home",
            "navigationOrder": "1",
            "subNavigationItems": []
        },
        {
            "navigationMenuId": "2",
            "parentNavigationMenuId": "0",
            "fullURL": "/top-nav-1/index",
            "contentSlug": "index",
            "contentAlias": "Index",
            "navigationAnchor": "Top Nav 1",
            "navigationOrder": "2",
            "subNavigationItems": []
        },
        {
            "navigationMenuId": "3",
            "parentNavigationMenuId": "0",
            "fullURL": "/top-nav-2/index",
            "contentSlug": "index",
            "contentAlias": "Index",
            "navigationAnchor": "Top Nav 2",
            "navigationOrder": "3",
            "subNavigationItems": [
                {
                    "navigationMenuId": "4",
                    "parentNavigationMenuId": "3",
                    "fullURL": "/top-nav-2/sub-nav-1",
                    "contentSlug": "sub-nav-1",
                    "contentAlias": "Sub Nav 1",
                    "navigationAnchor": "Sub Nav 1",
                    "navigationOrder": "1"
                },
                {
                    "navigationMenuId": "5",
                    "parentNavigationMenuId": "3",
                    "fullURL": "/top-nav-2/sub-nav-2",
                    "contentSlug": "sub-nav-2",
                    "contentAlias": "Sub Nav 2",
                    "navigationAnchor": "Sub Nav 2",
                    "navigationOrder": "2"
                },
                {
                    "navigationMenuId": "6",
                    "parentNavigationMenuId": "3",
                    "fullURL": "/top-nav-2/sub-nav-3",
                    "contentSlug": "sub-nav-3",
                    "contentAlias": "Sub Nav 3",
                    "navigationAnchor": "Sub Nav 3",
                    "navigationOrder": "3"
                },
                {
                    "navigationMenuId": "7",
                    "parentNavigationMenuId": "3",
                    "fullURL": "/top-nav-2/sub-nav-4",
                    "contentSlug": "sub-nav-4",
                    "contentAlias": "Sub Nav 4",
                    "navigationAnchor": "Sub Nav 4",
                    "navigationOrder": "4"
                }
            ]
        },
        {
            "navigationMenuId": "8",
            "parentNavigationMenuId": "0",
            "fullURL": "/top-nav-3/index",
            "contentSlug": "index",
            "contentAlias": "Top Nav 3",
            "navigationAnchor": "Top Nav 3",
            "navigationOrder": "4",
            "subNavigationItems": []
        },
        {
            "navigationMenuId": "9",
            "parentNavigationMenuId": "0",
            "fullURL": "/top-nav-4/index",
            "contentSlug": "index",
            "contentAlias": "Top Nav 4",
            "navigationAnchor": "Top Nav 4",
            "navigationOrder": "5",
            "subNavigationItems": [
                {
                    "navigationMenuId": "10",
                    "parentNavigationMenuId": "9",
                    "fullURL": "/top-nav-4/sub-nav-1",
                    "contentSlug": "sub-nav-1",
                    "contentAlias": "Sub Nav 1",
                    "navigationAnchor": "Sub Nav 1",
                    "navigationOrder": "1"
                },
                {
                    "navigationMenuId": "11",
                    "parentNavigationMenuId": "9",
                    "fullURL": "/top-nav-4/sub-nav-2",
                    "contentSlug": "sub-nav-2",
                    "contentAlias": "Sub Nav 2",
                    "navigationAnchor": "Sub Nav 2",
                    "navigationOrder": "2"
                },
                {
                    "navigationMenuId": "12",
                    "parentNavigationMenuId": "9",
                    "fullURL": "/top-nav-4/sub-nav-3",
                    "contentSlug": "sub-nav-3",
                    "contentAlias": "Sub Nav 3",
                    "navigationAnchor": "Sub Nav 3",
                    "navigationOrder": "3"
                }
            ]
        },
        {
            "navigationMenuId": "13",
            "parentNavigationMenuId": "0",
            "fullURL": "/top-nav-5/index",
            "contentSlug": "index",
            "contentAlias": "Top Nav 5",
            "navigationAnchor": "Top Nav 5",
            "navigationOrder": "6",
            "subNavigationItems": []
        }
    ]

Please let me know you can think of a better way to handle this than what i am thinking. Thanks!

Upvotes: 1

Views: 3159

Answers (2)

tux-rampage
tux-rampage

Reputation: 108

Use objects instead of arrays. In PHP >= 5.0 Objects will be references when assigning them. Then you'll need to loop over the result of these objects and build the navigation tree.

I'd use an item class to encapsulate the logics and providing a toArray() method and a toJson() method which consumes the result of toArray() and passes them to json_encode().

Example:

public function toArray()
{
    $data = array(
        'navigationMenuId' => $this->id,
        // ...
        'subNavigationItems' => array()
    )

    foreach ($this->children as $child) {
        $data['subNavigationItems'][] = $child->toArray();
    }

    return $data;
}

public function toJson()
{
    return json_encode($this->toArray());
}

Upvotes: 2

Matt
Matt

Reputation: 5567

Maybe I'm missing something about the format you want, but why not just use json_encode? Does it not produce the correct ouput?

http://php.net/manual/en/function.json-encode.php

$json = json_encode($input);

Oh, never mind, I see in your output you need to move things around the tree. json_encode would be used after generating the correct php array.

Upvotes: 0

Related Questions