【问题标题】:PHP - How to display data from array into a tree or table?PHP - 如何将数组中的数据显示到树或表中?
【发布时间】:2011-06-08 22:57:48
【问题描述】:

目前,我已从 SELECT 检索数据并转换为 PHP assoc 数组。因此,我得到了这个数组。

[0] => array
(
    [Gattung] => 'Gattung_A'
    [Untergattung] => null
    [Sektion] => null
    [Untersektion] => null
    [Serie] => null
    [Unterserie] => null
    [Art] => 'Art_A'
    [Unterart] => null
    [Varietaet] => null
    [SubVarietaet] => null
    [Form] => 'Form_A'
    [Unterform] => null
    [SpezialForm] => null
    [Hybride] => null
    [Blendling] => null
    [Sorte] => null
)
[1] => array
(
    [Gattung] => 'Gattung_A'
    [Untergattung] => null
    [Sektion] => null
    [Untersektion] => null
    [Serie] => null
    [Unterserie] => null
    [Art] => 'Art_B'
    [Unterart] => null
    [Varietaet] => 'Variant_G'
    [SubVarietaet] => null
    [Form] => 'Form_B'
    [Unterform] => null
    [SpezialForm] => null
    [Hybride] => null
    [Blendling] => null
    [Sorte] => null
)
[2] => array
(
    [Gattung] => 'Gattung_B'
    [Untergattung] => null
    [Sektion] => null
    [Untersektion] => null
    [Serie] => null
    [Unterserie] => null
    [Art] => 'Art_C'
    [Unterart] => null
    [Varietaet] => 'Variant_A'
    [SubVarietaet] => null
    [Form] => null
    [Unterform] => null
    [SpezialForm] => null
    [Hybride] => null
    [Blendling] => null
    [Sorte] => null
)
......... 
Nearly ~300k records

到目前为止,我已经使用array_unique 将我的数组固定为基于唯一值的一维数组。这是我的结果:

(
  [0] => 'Gattung|Gattung_A'
  [1] => 'Art|Art_A'
  [3] => 'Form|Form_A'
  [5] => 'Art|ArtB'
  [7] => 'Varietaet|Variant_G'
  [9] => 'Form|Form_G'
  [11] => 'Gattung|Gattung_B'
  [13] => 'Art|Art_C'
  [15] => 'Varietaet|Variant_A'
}

但是,我的结果没有很好地分组。我需要将其显示在页面上,因此类似于构建分层系统。

问题: @Melsi 我希望我的第二次编辑能净化我的问题。

如何将数据显示到树中 表格(见编辑 2)或表格(见编辑 1)?

谢谢。

编辑 1:

我正在做的是在几个表中创建类似 FULLTEXT 搜索的内容。这是连接所有表的查询: (所有 FK 对每个表的 id 都有索引)

SELECT 
    tGa.Gattung AS Gattung, 
    tUG.Untergattung AS Untergattung,
    tSe.Sektion AS Sektion,
    tUS.Untersektion AS Untersektion,
    tSer.Serie AS Serie,
    tUser.Unterserie AS Unterserie, 
    tA.Art AS Art,
    tUa.Unterart AS Unterart,
    tV.Varietaet AS Varietaet, 
    tSV.SubVarietaet AS SubVarietaet,
    tF.Form AS Form, 
    tUF.Unterform AS Unterform,
    tSF.SpezialForm AS SpezialForm, 
    tH.Hybride AS Hybride, 
    tBL.Blendling AS Blendling, 
    tSo.Sorte AS Sorte 
FROM 
        botanischername AS tBot
    LEFT JOIN ( gattung AS tGa ) ON ( tBot.ID_Ga = tGa.ID_Ga )
    LEFT JOIN ( untergattung AS tUg ) ON (  tBot.ID_UG = tUg.ID_UG )
    LEFT JOIN ( sektion AS tSe ) ON ( tSe.ID_Se = tBot.ID_Se )
    LEFT JOIN ( untersektion AS tUS ) ON ( tUS.ID_US = tBot.ID_US )
    LEFT JOIN ( serie AS tSer ) ON ( tSer.ID_Ser = tBot.ID_Ser )
    LEFT JOIN ( unterserie AS tUSer ) ON ( tUser.ID_USer = tBot.ID_USer )
    LEFT JOIN ( art AS tA ) ON ( tA.ID_A = tBot.ID_A )
    LEFT JOIN ( unterart AS tUa ) ON ( tUa.ID_UA = tBot.ID_UA )
    LEFT JOIN ( varietaet AS tV ) ON ( tV.ID_V = tBot.ID_V )
    LEFT JOIN ( subvarietaet AS tSV ) ON ( tSV.ID_SV = tBot.ID_SV)
    LEFT JOIN ( form AS tF ) ON ( tF.ID_F = tBot.ID_F )
    LEFT JOIN ( unterform AS tUF ) ON ( tUF.ID_UF = tBot.ID_UF )
    LEFT JOIN ( spezialform AS tSF ) ON ( tSF.ID_SF = tBot.ID_SF )
    LEFT JOIN ( hybride AS tH ) ON ( tH.ID_H = tBot.ID_H )
    LEFT JOIN ( blendling AS tBL ) ON ( tBL.ID_BL = tBot.ID_BL )
    LEFT JOIN ( sorte AS tSo ) ON ( tSo.ID_So = tBot.ID_So )
    LEFT JOIN ( status AS tST 
                 CROSS JOIN pflanze AS tPfl) ON 
                        ( tST.ID_ST = tBot.ID_ST AND tPfl.ID = tBot.ID )

    WHERE 
            tGa.Gattung LIKE #1_Word#        OR 
            tUG.Untergattung LIKE #2_Word#  OR
    tSe.Sektion LIKE #3_Word# OR 
    tUS.Untersektion LIKE #4_Word# OR 
    tSer.Serie LIKE #5_Word# OR 
    tUser.Unterserie LIKE #6_Word# OR
    tA.Art LIKE #7_Word# OR
    tUa.Unterart LIKE #8_Word# OR
    tV.Varietaet LIKE #9_Word# OR 
    tSV.SubVarietaet LIKE #10_Word# OR
    tF.Form LIKE #11_Word# oR 
    tUF.Unterform LIKE #12_Word# OR 
    tSF.SpezialForm LIKE #13_Word# oR
    tH.Hybride LIKE #14_Word# oR
    tBL.Blendling LIKE #15_Word# OR
    tSo.Sorte LIKE #16_Word#

我知道使用LIKE %xxx% OR 是一个繁重的过程。如果您想建议我另一种方式,那很好。

我的预期结果是这样的:

________________________________________________________________________________
|      |             |       |______________________________Detail_____________| 
| Num  | Gattung     | Art   | Form      | Varietaet  | ...... | the other cols|
|------|-------------|-------|-----------|------------|--------|---------------|
| 1.   | Gattung A   | Art A | Form A    |            |        |               |
|      |             | <same | Form B    |            |        |               |
|      |    | data or Art A> |           |            |        |               |
|      |             | Art B | Form B    | Variant G  |        |               |
| 2.   | Gattung B   | Art C |           | Variant A  |        |               |
-------------------------------------------------------------------------------
                                                              Back 1 2 3   Next   

编辑 2:简明问题。

或者以树的形式,

                   ----- Art A ------ Form A
                   |               |
                   |               -- Form B
1.   Gattung A ----|---- Art B ------ Form B ---- Variant G

2.   Gattung B --------- Art C ------ Variant A 

 ... And so on.

【问题讨论】:

  • 当你说“目前,我有一个从 SELECT 检索并转换为 PHP assoc 数组的数据”——你能把你正在使用的代码放在上面吗?我会更改该代码——QUERY、php 或两者兼而有之。然后你就不必在以后的处理中那么繁重了。

标签: php arrays tree multidimensional-array


【解决方案1】:

@exodream

感谢您的评论。

这是我对您问题的新回答,它避免了空行,如果您需要避免空列或需要其他信息,请告诉我。

<?php 

        //make the labels
        $labels=array('Gattung','Untergattung','Sektion','Untersektion','Serie',
    'Unterserie','Art','Unterart','Varietaet','SubVarietaet','Form','Unterform',
    'SpezialForm','Hybride','Blendling','Sorte' );  

    // Make a MySQL Connection
    mysql_connect("localhost", "root", "") or die(mysql_error());

    //select database
    mysql_query("drop database if exists `test_db`;")or die(mysql_error());  
    mysql_query("create database `test_db`;")or die(mysql_error());  
    mysql_select_db("test_db") or die(mysql_error());

    //create table 
    mysql_query(" drop table if exists `test_table`;")or die(mysql_error());  


    mysql_query("   
    CREATE TABLE `test_table` (
        `Gattung` char(30)  NULL  ,
        `Untergattung` char(30)  NULL  ,
        `Sektion` char(30)  NULL  , 
        `Untersektion` char(30)  NULL  ,
        `Serie` char(30)  NULL  ,
        `Unterserie` char(30)  NULL  ,
        `Art` char(30)  NULL  ,
        `Unterart` char(30)  NULL  ,    
        `Varietaet` char(30)  NULL  ,
        `SubVarietaet` char(30)  NULL  ,
        `Form` char(30)  NULL  ,
        `Unterform` char(30)  NULL  ,
        `SpezialForm` char(30)  NULL  ,
        `Hybride` char(30)  NULL  ,
        `Blendling` char(30)  NULL  ,
        `Sorte` char(30)  NULL   
    )
    COLLATE='latin1_swedish_ci'
    ENGINE=InnoDB;") or die(mysql_error());  



     mysql_query("INSERT INTO `test_table`  VALUES 
     ('Gattung_A',null,null,null,null,null,'Art_A',null,null,null,'Form_A',null,null,null,null,null  ) ") 
     or die(mysql_error());    

     mysql_query("INSERT INTO `test_table`  VALUES 
     ('Gattung_A',null,null,null,null,null,'Art_A',null,null,null,'Form_A',null,null,null ,null,null ) ") 
     or die(mysql_error());    

     mysql_query("INSERT INTO `test_table`  VALUES 
     ('Gattung_B',null,null,null,null,null,'Art_C',null,'Variant_A',null,null,null,null,null,null,null ) ") 
     or die(mysql_error());   

     mysql_query("INSERT INTO `test_table`  VALUES 
     (null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null ) ") 
     or die(mysql_error());   


     mysql_query("INSERT INTO `test_table`  VALUES 
     ('Gattung_Q',null,null,null,null,null,'Art_C',null,'Variant_A',null,'Form_W',null,null,null,null,null ) ") 
     or die(mysql_error());   

     mysql_query("INSERT INTO `test_table`  VALUES 
     ('Gattung_Q',null,'test','test','test','test','Art_S','test','Variant_Y','test','Form_H','test','test','test','test','last' ) ") 
     or die(mysql_error());   


        //get result        
        $result = mysql_query("SELECT * FROM `test_table` ;")
           or die(mysql_error());   



    normal_display();      
    non_empty_row_display();        
    non_empty_column_display(); 

    function non_empty_row_display()
    { 
        //get data
        global $result;
        $final_array=array();   

        global $result;
        mysql_data_seek ($result , 0);

        print '<b><br><h2>TABLE: 2 NON EMPTY VALUES OF EACH ROW</h2></b>';
        print '<table border=7 bordercolor=orange >';
        $index=0;
        $color=array('#66CCFF','#00FF00');
        //for every row of the table
        while($row = mysql_fetch_row($result))
        {
            $current_row='';
            //for every coloumn
            foreach ($row as  $value) 
                //if value is not null
                if($value!=null)//then keep it 
                    $current_row .=  $value.' | ';

            if($current_row!='')
                echo '<tr bgcolor=',$color[$index%2],'><th>ROW ',$index++,'</th><td>',$current_row,'</td></tr>',
                        '<tr><td colspan=2 height=5 bgcolor=pink></td></tr>'; 
        }//while
        echo '</table>'; 

    }//function


    function normal_display()
    {
        print '<b><h2>TABLE:1 Normal display</h2></b>';
        print '<table border=1><tr>';
        global $labels;
        foreach($labels as $value)
            echo '<th>',$value,'</th>';
        print '</tr>';
        global $result;
        while($row = mysql_fetch_row($result)) 
        {
            print '<tr>';
            foreach($row as $value)
                echo '<td>',$value,'&nbsp;</td>';
            print '</tr>';
        }//while
        print '</table>';
     }//function



     function non_empty_column_display()
    { 
        //get data
        global $result;   
        mysql_data_seek ($result , 0);

        //for every row of the table
        $final_column=array();
        while($row = mysql_fetch_row($result)) 
            //for every coloumn
            foreach ($row as  $key => $value) 
                //if value is not null
                if($value!=null)
                    //if $final_column[$key] exists append value to it, otherwise assign value 
                    $final_column[$key]=(isset($final_column[$key]))?$final_column[$key].=$value.'<br>':$value.' <br> ';


        echo '<br><br><h2>Array:1 </h2>The coloumn with index 6 is placed before the one with index 2 in this array 
        because its first non empty value is fetched earlier. Check for your self:<br>';
        echo '<pre>',strip_tags(print_r($final_column,true)),'</pre>';


        //for each mysql table coloumn name
        global $labels;
        foreach($labels as $key => $value)
            //if it exists in the result
            if(array_key_exists($key,$final_column))
                //keep it
                $label_header=(isset($label_header))?$label_header.='<th>'.$value.'</th>':'<th>'.$value.'</th>';


        ksort($final_column);
        echo '<br><br><h2>Array:2 </h2>We can order this. Check for your self:<br>';
        echo '<pre>',strip_tags(print_r($final_column,true)),'</pre>';

        echo '<br><b><h2>TABLE:3 </h2>THIS IS A TABLE WITH NON EMPTY COLOUMNS<b>';
        echo '<table border=1>',$label_header,'<tr>';
        foreach($final_column as $value)
                echo '<td valign=top>',$value,'</td>';
        echo '</tr></table>';



    }//function

    ?>

我已经修复了第 147 行和第 161 行(对于前面的示例),这是一个警告,我们必须在连接之前检查变量是否存在,在您的示例中它将是:

147:

$final_column[$key]=(isset($final_column[$key]))?$final_column[$key].=$value.'<br>':$value.' <br> ';

161:

$label_header=(isset($label_header))?$label_header.='<th>'.$value.'</th>':'<th>'.$value.'</th>';

【讨论】:

  • 在第 68 行经常注意到未定义的偏移量。而且表格的行打印效果也不好。如果我再添加一个数据,(即 Gattung A,与 Art B)。我看不出“Art B”的“Gattung”是什么。
  • 非常感谢您的回答。请查看我的“已编辑”问题以获取更多详细信息。顺便说一句,我的 php 日志中仍然出现“第 147 行未定义的偏移量”(我使用 PHP 5.3.4 和 WAMP 2.0)。
  • 我已经把我的问题删减了。后来我才意识到我真正需要的是,显示就像一棵分层树(就像在生物学命名系统中一样)。
  • Fix Sentences “...我真正需要的是,显示一个层次树(就像在生物命名系统中一样)。”
  • blogs.sitepoint.com/hierarchical-data-database 中的概念是一样的,但实现肯定是不同的。因为没有必要使用表来更新数据。如果您在我的第二次编辑中看到更仔细,我需要的是非二叉树。
【解决方案2】:

1) 如果您可以在 SQL 中进行排序/分组/聚合,那么请在 SQL 中进行 - 而不是在 PHP 中。 SQL 和 rDBMS 就是为此设计和优化的。

2) PHP 没有多维数组——它们是分层的。

3) 如果您不想在数组中出现空值,请不要将它们放在那里

4) 如果您的数据中的结果集有一个主键,则使用该主键作为您的数组键

while ($r=mysql_fetch_assoc($result)) {
    foreach($r as $key=>$val) {
      if ($val || $val===0 || $val===false) {
         $array[$r['Art']][$key]=$val;
      }
    }
}

【讨论】:

  • @aymcbean (1)我已经很好地分组了我的数据,并删除了不必要的数据。命名系统需要几个表来连接。 (2)如果我笨,请原谅我,但是我的老师对我说,当你声明$arr[][]时,是不是意味着我声明了二维数组? (3) 不可能。 (4) 我有主键,但有什么用?这不是必需的。作为替代,我将Gattung's name field 分组为一个新键。
猜你喜欢
  • 1970-01-01
  • 2017-08-15
  • 1970-01-01
  • 1970-01-01
  • 2021-08-17
  • 1970-01-01
  • 2018-04-25
  • 1970-01-01
  • 2013-09-17
相关资源
最近更新 更多