在生成分层列表php时避免嵌套foreach循环


Avoiding nested foreach loops when making a hierarchical list php

我现在正在制作一个表格来显示会计数据,发票分为许可证、年度、半年和季度。发票来自一个2d数组的查询,如下所示:

array(
    'invoice0' = array(data),
    'invoice2' = array(data),
    'invoice3' = array(data),
    'invoice4' = array(data),
    'invoice5' = array(data),
    'invoice1' = array(data)
)

目前,我一直在使用一个四个深度嵌套的foreach循环来创建一个5d数组结构来组织行,每个级别都有数据行,这似乎相当糟糕。例如:

'License' = array(
  'Year0' = array(
    'Half0' = array(
      'Quarter0' = array(
        'invoice0' = array(data),
        'invoice1' = array(data)
      ),
      'QData' = array(data)
    ),
    'HData' = array(data)
    'Half1' = array(
      'Quarter0' = array(
        'invoice3' = array(data),
        'invoice4' = array(data)
      ),
      'Quarter1' = array(
        'invoice5' = array(data),
        'invoice6' = array(data)
      ),
      'QData' = array(data)
    ),
    'HData' = array(data)
  ),
  'YData' = array(data)
)

等等。每个级别的数据需要在每个发票的数据中包括一个金额的总和。我试图实现的最终产品只是一个表的一堆行(或列表项;对于这个项目,我仅限于表结构),它们是可扩展的。因此:

<tr>License info</tr>
<tr>License info</tr>
<tr>License info</tr>
<tr>License info</tr>

当你点击一个:

<tr>License info</tr>
<tr>License info</tr>
<tr>Year1 Info</tr>
<tr>Year2 Info</tr>
<tr>Year3 Info</tr>
<tr>License info</tr>
<tr>License info</tr>

最终:

<tr>License info</tr>
<tr>License info</tr>
<tr>Year1 Info</tr>
<tr>Year2 Info</tr>
<tr>Half1 Info</tr>
<tr>Quarter1 Info</tr>
<tr>Quarter2 Info</tr>
<tr>Invoice1 Info</tr>
<tr>Invoice2 Info</tr>
<tr>Invoice3 Info</tr>
<tr>Quarter3 Info</tr>
<tr>Quarter4 Info</tr>
<tr>Half2 Info</tr>
<tr>Year3 Info</tr>
<tr>License info</tr>
<tr>License info</tr>

那么,有什么想法吗?有没有什么方法可以避免如此复杂的数据操作,同时仍然为我提供一个5层的分层下拉列表?

好吧,我不完全明白你到底想要什么,但我做到了,有点困惑,呵呵:

function get_data($data, $level = 0)
{
    $html = '';
    foreach ($data as $name => $val) {
        if (!is_int($name)) {
            if (!$level)
                $html .= '<tr>';
            $html .= '<ul>';
            $html .= '<li><span class="parent">'.$name.'</span>';
            $html .= get_data($val, $level + 1);
            $html .= '</li></ul>';
            if (!$level)
                $html .= '</tr>';
        } else {
            $html .= '<ul><li>'.$val.'</li></ul>';
        }
    }
    return $html;
}

HTML应该是这样的(使用jQuery):

<style>
span.parent {
    cursor:pointer;
}
ul ul {
    display:none;
}
</style>
<table>
<?php echo get_data($data) ?>
</table>
<script>
$('span.parent').click(function(){
    if ($(this).hasClass('open')) {
        $(this).parent().children('ul').hide();
        $(this).removeClass('open');
    } else {
        $(this).parent().children().show();
        $(this).addClass('open');
    }
})
</script>

我用下面的数组尝试了一下。。。很好,它起了作用,但我不知道这是否是你想要的。

$data = array(
    'License' => array(
        'Year0' => array(
            'Half0' => array(
                'Quarter0' => array(
                    'invoice0' => array('data'),
                    'invoice1' => array('data')
                ),
                'QData' => array('data')
            ),
            'HData' => array('data'),
            'Half1' => array(
                'Quarter0' => array(
                    'invoice3' => array('data'),
                    'invoice4' => array('data')
                ),
                'Quarter1' => array(
                    'invoice5' => array('data'),
                    'invoice6' => array('data')
                ),
                'QData' => array('data')
            ),
            'HData' => array('data')
        ),
        'YData' => array('data')
    ),
    'License2' => array(
        'Year0' => array(
            'Half0' => array(
                'Quarter0' => array(
                    'invoice0' => array('data'),
                    'invoice1' => array('data'),
                ),
                'QData' => array('data')
            ),
            'HData' => array('data'),
            'Half1' => array(
                'Quarter0' => array(
                    'invoice3' => array('data'),
                    'invoice4' => array('data')
                ),
                'Quarter1' => array(
                    'invoice5' => array('data'),
                    'invoice6' => array('data')
                ),
                'QData' => array('data')
            ),
            'HData' => array('data')
        ),
        'YData' => array('data')
    )
);