如何使用PHP将MySQL查询结果作为嵌套数组?

时间:2017-01-11 08:51:15

标签: php mysql arrays

假设我有这个简单的表,其中pos_level是位置的级别,pos_under是位于其顶部的位置的PID。

在第1级,我有'总经理'和'主管'。

在第2级,在'总经理(PID:1)'下:'助理。经理',在'主管(PID:2)':'营销'下。

在第3级,在'助理。经理(PID:3)':'销售'& '购买',在'市场营销(PID:2):无。

+-----+-----------------+-----------+-----------+
| PID | pos_name        | pos_level | pos_under |
+-----+-----------------+-----------+-----------+
|   1 | General Manager |     1     |     0     |
|   2 | Supervisor      |     1     |     0     |
|   3 | Asst. Manager   |     2     |     1     |
|   4 | Sales           |     3     |     3     |
|   5 | Purchase        |     3     |     3     |
|   6 | Marketing       |     2     |     2     |
+-----+-----------------+-----------+-----------+

现在我如何进行查询,以便得到一个嵌套数组,如下所示:

Array
(
    [0] => Array
        (
            [pos_level] => 1
            [pos_name] => General Manager
            [pos_under] => Array
                (
                    [0] => Array
                        (
                            [pos_level] => 2
                            [pos_name] => Asst. Manager
                            [pos_under] => Array
                                (
                                    [0] => Array
                                        (
                                            [pos_level] => 3
                                            [pos_name] => Sales
                                        )

                                    [1] => Array
                                        (
                                            [pos_level] => 3
                                            [pos_name] => Purchase
                                        )

                                )

                        )

                )

        )

    [1] => Array
        (
            [pos_level] => 1
            [pos_name] => Supervisor
            [pos_under] => Array
                (
                    [0] => Array
                        (
                            [pos_level] => 2
                            [pos_name] => Marketing
                            [pos_under] => Array
                                (
                                )

                        )

                )

        )

)

我已尝试使用多个查询并使用array_push使用结果,但我喜欢大约100+ pos_name,我认为它很乱,我也尝试使用循环来保持每个级别和下的运行查询,也尝试使用每个级别有多个表,但我希望我只能使用1个表,并能够将结果作为上面的嵌套数组进行查询,以便在我的应用程序中进一步使用。

非常欢迎所有答案,评论和建议。谢谢。

1 个答案:

答案 0 :(得分:0)

如上文评论中所述,我一般怀疑你所遵循的方法是好的。那是因为它不会扩展!您尝试从数据库中获取所有条目并将它们打包到单个分层数组中。这意味着您在内存中创建每个条目的多个副本。越来越多的参赛作品将会发生什么?你面临不断增加的脚本内存消耗,这显然会使它最终失败。

然而,我接受了挑战并实施了一个小型演示,演示如何在引用的帮助下巧妙地构建这样的嵌套结构。这样的引用不仅简化了嵌套结构的创建,还通过防止条目一次又一次地按值复制来减少内存占用。然而,这将解决上述这种方法的一般扩展问题,它只能帮助减少它。

我还冒昧地对你的方法进行了一些小修改,并引入了一个新的属性" pos_over"在条目下保留条目。有两个原因:

  1. 删除原始可用数据通常不是一个好主意,特别是不要用改变的含义替换它
  2. 术语的含义" pos_under"是描述给定条目的其他条目(将被放置)。但是来自"鞋帮"条目观点"下面"它不应该被" pos_under"引用,对吧?这与该术语的原始含义相矛盾。
  3. 以下代码依赖于数据库以进行演示。相反,它从CSV字符串中读取原始数据并解析它。通过评论进一步标记了所需结构结构的实际构建。还应该提到的是,代码要求原始数据仅在声明后引用其他条目。因此,如果从上到下处理,则另一个条目下的每个条目都可以预期其他条目已经存在。

    注意,构建嵌套结构的实际代码只包含12个聪明的行......

    <?php
    
    // the raw CSV data
    $csvText = <<<CSV
    PID|pos_name|pos_level|pos_under
    1|General Manager|1|0
    2|Supervisor|1|0
    3|Asst. Manager|2|1
    4|Sales|3|3
    5|Purchase|3|3
    6|Marketing|2|2
    CSV;
    
    // praparation of CSV data
    foreach (explode("\n", $csvText) as $csvRow) {
        $csvData[] = str_getcsv($csvRow, '|');
    }
    $csvTitle = array_shift($csvData);
    
    $table = [];
    foreach ($csvTitle as $titleKey=>$titleValue){
        foreach ($csvData as $csvRow=>$csvColumn) {
            foreach ($csvColumn as $csvKey=>$csvValue) {
                $table[$csvRow][$csvTitle[$csvKey]] = $csvValue;
            }
        }
    }
    
    // creation of the structure
    $catalog = [];
    $structure = [];
    foreach ($table as $key=>&$entry) {
        $entry['pos_over'] = [];
        if ($entry['pos_under'] == 0) {
            $structure[] = &$entry;
            $catalog[$entry['PID']] = &$structure[count($structure)-1];
        } else {
            $catalog[$entry['pos_under']]['pos_over'][] = &$entry;
            $catalog[$entry['PID']] = &$catalog[$entry['pos_under']]['pos_over'][count($catalog[$entry['pos_under']]['pos_over'])-1];
        }
    }
    
    // demonstration output
    print_r($structure);
    

    以上实验的输出是:

    Array
    (
        [0] => Array
            (
                [PID] => 1
                [pos_name] => General Manager
                [pos_level] => 1
                [pos_under] => 0
                [pos_over] => Array
                    (
                        [0] => Array
                            (
                                [PID] => 3
                                [pos_name] => Asst. Manager
                                [pos_level] => 2
                                [pos_under] => 1
                                [pos_over] => Array
                                    (
                                        [0] => Array
                                            (
                                                [PID] => 4
                                                [pos_name] => Sales
                                                [pos_level] => 3
                                                [pos_under] => 3
                                                [pos_over] => Array
                                                    (
                                                    )
    
                                            )
    
                                        [1] => Array
                                            (
                                                [PID] => 5
                                                [pos_name] => Purchase
                                                [pos_level] => 3
                                                [pos_under] => 3
                                                [pos_over] => Array
                                                    (
                                                    )
    
                                            )
    
                                    )
    
                            )
    
                    )
    
            )
    
        [1] => Array
            (
                [PID] => 2
                [pos_name] => Supervisor
                [pos_level] => 1
                [pos_under] => 0
                [pos_over] => Array
                    (
                        [0] => Array
                            (
                                [PID] => 6
                                [pos_name] => Marketing
                                [pos_level] => 2
                                [pos_under] => 2
                                [pos_over] => Array
                                    (
                                    )
    
                            )
    
                    )
    
            )
    
    )