2015-08-28 228 views
0

我遇到的情況,我有一個樹狀結構的數據是這樣的:PHP樹結構HTML表

$tree = array(
    1 => array(
     4 => array(), 
     5 => array() 
    ), 
    2 => array(
     6 => array(), 
     7 => array(
      11 => array() 
     ), 
     8 => array(
      12 => array(
       14 => array(), 
       15 => array() 
      ) 
     ), 
    ), 
    3 => array(
     9 => array(), 
     10 => array(
      13 => array() 
     ) 
    ) 
); 

如何使用PHP遞歸函數這樣創建的HTML表格:

1   |  2   |  3  | 
4  5 | 6 7 | 8 | 9  10 | 
      |  |11 | 12 |  | 13 | 
         |14 |15 | 

我正在使用以下的PHP代碼:

function tree(array $data, &$tree = array(), $level = 0) { 
    // init 
    if (!isset($tree[$level])) $tree[$level] = array(count($array)); 

    foreach ($data as $key => $value) { 

     // if value is an array, push the key and recurse through the array 
     if (is_array($value)) { 
      $tree[$level][] = $key; 
      tree($value, $tree, $level+1); 
     } 
     // otherwise, push the value 
     else { 
      $tree[$level][] = $value; 
     } 
    } 
} 

function make_table($array) 
{ 
    $output = ''; 
    foreach($array as $item => $tr) 
    { 
     $c = 100/count($tr); 
     $output .= "<tr>"; 

     foreach($tr as $th => $val) 
     {   
      $output .= "<th style='width:" . $c . "%'>" . $val . "</th>"; 
     } 

     $output .= "</tr>";  
    } 

    return $output; 
} 

但是,上面的代碼不處理像第三行第一列。

1 | 2 | 3 | 
4 | 5 | 6 | 7 | 8 | 9 | 10 | 
11 | 12 | 13 | 
14 | 15 | 
+0

使用合併單元格,不寬。 –

+0

如果可以將該數組轉換爲具有固定列數的二維數組,那將很簡單。 –

+0

做一棵完整的樹會比較容易,而不是空葉,因爲元素的列數在任何時候都是已知的。那麼沒有值的元素可以留空。 – syck

回答

0

您需要一些方法來跟蹤colspans和表中每個單元格的位置,然後用空單元格填充空位。

我這今天撰文稱,它似乎對你的例子很好地工作:

<?php 

$tree = [ 
    'Table Title' => [ 
     1 => [ 
      4 => [], 
      5 => [] 
     ], 
     2 => [ 
      6 => [], 
      7 => [ 
       11 => [] 
      ], 
      8 => [ 
       12 => [ 
        14 => [], 
        15 => [] 
       ] 
      ], 
     ], 
     3 => [ 
      9 => [], 
      10 => [ 
       13 => [] 
      ] 
     ] 
    ] 
]; 

// Loop over the tree. Every leaf in the root of the tree 
// gets his own table(s). 
foreach ($tree as $name => $leaves) { 
    $table = []; 
    parseLeaf($name, $leaves, $table); 
    $table = cleanupRows($table); 

    output($table); 
} 

/** 
* Convert a leaf in the tree to an array to be used to print the tables. 
* The span of a leaf is either the sum of its children's spans, 
* or 1 if it has no children. 
* 
* @param string $name 
* @param array $leaves 
* @param array $table 
* @param int $level 
* @param int $position 
* 
* @return int 
*/ 
function parseLeaf($name, $leaves, &$table, $level = 0, $position = 0) 
{ 
    if (!empty($leaves)) { 
     $span = 0; 

     foreach ($leaves as $leafName => $childLeaves) { 
      $span += parseLeaf(
       $leafName, 
       $childLeaves, 
       $table, 
       $level + 1, 
       $position + $span 
      ); 
     } 
    } else { 
     $span = 1; 
    } 

    $table[$level][$position] = getCell($name, $span);; 

    return $span; 
} 

/** 
* Insert empty cells where needed and sort by keys. 
* 
* @param array $table 
* 
* @return array 
*/ 
function cleanupRows($table) 
{ 
    $width = $table[0][0]['span']; 

    foreach ($table as $rowNumber => $row) { 
     $spanSoFar = 0; 
     foreach ($row as $position => $cell) { 
      addExtraCells($table, $spanSoFar, $rowNumber, $position); 
      $spanSoFar += $cell['span']; 
     } 
     addExtraCells($table, $spanSoFar, $rowNumber, $width); 
     ksort($table[$rowNumber]); 
    } 
    ksort($table); 

    return $table; 
} 

/** 
* @param array $table 
* @param int $spanSoFar 
* @param int $rowNumber 
* @param int $position 
*/ 
function addExtraCells(&$table, &$spanSoFar, $rowNumber, $position) 
{ 
    while ($spanSoFar < $position) { 
     $table[$rowNumber][$spanSoFar] = getCell(); 
     $spanSoFar += 1; 
    } 
} 

/** 
* @param string $name 
* @param int $span 
* 
* @return array 
*/ 
function getCell($name = '', $span = 1) 
{ 
    return ['name' => $name, 'span' => $span]; 
} 

/** 
* Print the table. 
* 
* @param array $table 
*/ 
function output($table) 
{ 
    echo '<table border="1">'; 
    foreach ($table as $row) { 
     echo '<tr>'; 
     foreach ($row as $cell) { 
      echo '<td colspan="' . $cell['span'] . '" align="center">'; 
      echo $cell['name']; 
      echo '</td>'; 
     } 
     echo '</tr>'; 
    } 
    echo '</table>'; 
}