PHP - 将数组转换为多维json对象

时间:2013-10-31 21:31:17

标签: php json multidimensional-array

我有一个查询SELECT * FROM NavigationMenu ORDER BY parentNavigationMenuId ASC, navigationOrder ASC,它将返回一个导航对象数组。我必须使用的结果如下:

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 (
    ),
  ),
)

这些对象中的任何一个都可以有子导航项(子项可以有其他子项等),这就是为什么每个导航项都有一个空数组subNavigationItems。我基本上想要使用navigationMenuIdparentNavigationMenuId属性并构建一个json对象,该对象具有嵌套在正确父级下的正确子级。我假设它可以用一系列循环来完成它的逻辑让我头疼。有人对如何实现这一点有任何想法?这是我想要的一个例子json(或类似的东西):

    [
        {
            "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": []
        }
    ]

请让我知道你能想到一个比我想的更好的办法来处理这个问题。谢谢!

2 个答案:

答案 0 :(得分:2)

使用对象而不是数组。在PHP> = 5.0中,对象将在分配时引用。 然后,您需要遍历这些对象的结果并构建导航树。

我使用一个item类来封装逻辑并提供一个toArray()方法和一个toJson()方法,它使用toArray()的结果并将它们传递给json_encode()。

示例:

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());
}

答案 1 :(得分:0)

也许我错过了您想要的格式,但为什么不使用json_encode?它不能产生正确的输出吗?

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

$json = json_encode($input);

哦,没关系,我在你的输出中看到你需要在树上移动东西。生成正确的php数组后将使用json_encode