嵌套数组的PHP递归迭代

问题描述:

我有以下数组,数组的深度不能被知道,因为数组可以有n个孩子。嵌套数组的PHP递归迭代

$menu = [ 
    [ 
     'name' => 'home', 
     'label' => 'Home', 
     'uri' => '/home', 
     'order' => 1, 
     'attributes' => [ 
      'class' => ['home-class', 'home-class-2'], 
      'id' => ['home-id'] 
     ] 
    ], [ 
     'name' => 'about', 
     'label' => 'About', 
     'uri' => '/about', 
     'order' => 2, 
     'attributes' => [ 
      'class' => [], 
      'id' => [] 
     ], 
     'child' => [ 
      [ 
       'name' => 'company_profile', 
       'label' => 'Company Profile', 
       'uri' => '/company-profile', 
       'order' => 1, 
       'attributes' => [ 
        'class' => [], 
        'id' => [] 
       ] 
      ], [ 
       'name' => 'team', 
       'label' => 'Team', 
       'uri' => '/team', 
       'order' => 2, 
       'attributes' => [ 
        'class' => ['team-class', 'team-class-2'], 
        'id' => ['team-id'] 
       ], 
       'child' => [ 
        [ 
         'name' => 'management_team', 
         'label' => 'Management Team', 
         'uri' => '/management-team', 
         'order' => 1, 
         'attributes' => [ 
          'class' => [], 
          'id' => [] 
         ] 
        ], 
        [ 
         'name' => 'development_team', 
         'label' => 'Development Team', 
         'uri' => '/development-team', 
         'order' => 2, 
         'attributes' => [ 
          'class' => [], 
          'id' => [] 
         ] 
        ], 

       ] 
      ], 
     ] 
    ], [ 
     'name' => 'services', 
     'label' => 'Services', 
     'uri' => '/services', 
     'order' => 3, 
     'attributes' => [ 
      'class' => [], 
      'id' => [] 
     ], 
     'child' => [ 
      [ 
       'name' => 'web_application', 
       'label' => 'Web Application', 
       'uri' => '/web-application', 
       'order' => 1, 
       'attributes' => [ 
        'class' => [], 
        'id' => [] 
       ] 
      ], [ 
       'name' => 'mobile_application', 
       'label' => 'Mobile Application', 
       'uri' => '/mobile-application', 
       'order' => 2, 
       'attributes' => [ 
        'class' => [], 
        'id' => [] 
       ] 
      ], [ 
       'name' => 'cms_development', 
       'label' => 'CMS Development', 
       'uri' => '/cms-development', 
       'order' => 3, 
       'attributes' => [ 
        'class' => [], 
        'id' => [] 
       ] 
      ], 
     ] 
    ] 
]; 

例如,我想循环并将数据传递给对象。

$nav = new Navigation\Menu('main'); 
foreach ($menu as $item) { 
    // Parent element 
    $navItem = new Navigation\Item($item['name']); 
    $navItem->setLabel($item['label']); 
    $navItem->setUri($item['uri']); 
    $nav->addItem($navItem); 
    if (isset($item['child']) && is_array($item['child'])) { 
     // First child 
     foreach ($item['child'] as $child1) { 
      $childItem1 = new Navigation\Item($child1['name']); 
      $childItem1->setLabel($child1['label']); 
      $childItem1->setUri($child1['uri']); 
      $navItem->addChild($childItem1); 
      if (isset($child1['child']) && is_array($child1['child'])) { 
       // Second child 
       foreach ($child1['child'] as $child2) { 
        $childItem2 = new Navigation\Item($child2['name']); 
        $childItem2->setLabel($child2['label']); 
        $childItem2->setUri($child2['uri']); 
        $childItem1->addChild($childItem2); 
       } 
      } 
     } 
    } 
} 

这有效,但有一个问题。正如你看到的,我手动循环每个孩子,我不想要这个,我正在寻找的是,它必须递归迭代数组,允许添加任何深度的任意数量的孩子。

我试着array_walk_recursive或自定义递归函数没有任何结果。任何指针解决这个表示赞赏。

谢谢。

+1

'RecursiveArrayIterator'似乎是不错的选择也许 – RamRaider

+0

我试过,用添加元素时所保持的孩子和深度的问题。 –

终于想出来了。

下面是我如何使用自定义递归函数。

function recursive($menu, &$nav, $child = false, $parent = null) 
{ 
    foreach ($menu as $page) { 
     $navItem = new Navigation\Item($page['name']); 
     if (false == $child) { 
      $nav->addItem($navItem); 
     } else { 
      $parent->addChild($navItem); 
     } 
     if (isset($page['child'])) { 
      recursive($page['child'], $nav, true, $navItem); 
     } 
    } 
} 

$nav = new Navigation\Menu('main'); 
recursive($menu, $nav); 

这是一个小的递归脚本,如果它是一个数组或对象,每个递归都会返回该对象。现在,这将需要一些编辑您的使用。但它应该给你一个起点。

function Navigation($item) { 
    if (is_object($item)) { 
     foreach (get_object_vars($item) as $property => $value) { 
      //If item is an object, then run recursively 
      if (is_array($value) || is_object($value)) { 
       $item->$property = Navigation($item); 
      } else { 
       $navItem->setLabel($item['label']); 
       $navItem->setUri($item['uri']); 
       $nav->addItem($navItem); 
      } 
     } 
     return $nav; 
    } elseif (is_array($item)) { 
     foreach ($item as $property => $value) { 
      //If item is an array, then run recursively 
      if (is_array($value) || is_object($value)) { 
       $item[$property] = Navigation($item); 
      } else { 
       $navItem->setLabel($item['label']); 
       $navItem->setUri($item['uri']); 
       $nav->addItem($navItem); 
      } 
     } 
     return $nav; 
    } 
    $navItem->setLabel($item['label']); 
    $navItem->setUri($item['uri']); 
    $nav->addItem($navItem); 
} 
+0

谢谢安德鲁,这有助于投票+1,我会发布正确的答案。 –

+1

很高兴我能帮到你。有时候,自定义循环脚本是最简单的方法。 – AndrewL