首页 > 解决方案 > 使用子 ID 拉取整个数组(树)分支 - PHP Arrauu

问题描述

首先,我确信以前曾以某种方式问过这个问题,但我不确定如何正确表达,所以请耐心等待一分钟。

我的商店脚本有一个 Category 数组,我的所有项目类别都分类到名为$categoryTree. 它将类别设置为与其c.parentcatid标签相关。它是使用以下函数构建的:

public function buildStoreCategoryTree(array $elements, $parentId = 0) {
    $branch = array();
    foreach ($elements as $element) {
        if ($element['c.parentcatid'] == $parentId) {
            $children = $this->buildStoreCategoryTree($elements, $element['c.id']);
            if ($children) {
                $element['children'] = $children;
            }
            $branch[] = $element;
        }
    }
    return $branch;
}

这是数据库结构的布局,其中所有数据都存储在类别信息中(整个内容都发送到上述函数):

在此处输入图像描述

最后,这是使用上述函数将其排序为树后的信息:

Array ( 
    [0] => Array ( 
        [0] => 1 [c.id] => 1 
        [1] => Radios [c.name] => Radios 
        [2] => radios [c.path] => radios 
        [3] => 0 [c.parentcatid] => 0 
        [children] => Array ( 
            [0] => Array ( 
                [0] => 2 [c.id] => 2 
                [1] => Motorola Radios [c.name] => Motorola Radios 
                [2] => motorola [c.path] => motorola 
                [3] => 1 [c.parentcatid] => 1 
                [children] => Array ( 
                    [0] => Array ( 
                        [0] => 3 [c.id] => 3 
                        [1] => Motorola Handheld Radios [c.name] => Motorola Handheld Radios 
                        [2] => handheld [c.path] => handheld 
                        [3] => 2 [c.parentcatid] => 2 
                    ) 
                    [1] => Array ( 
                        [0] => 4 [c.id] => 4 
                        [1] => Motorola Mobile Radios [c.name] => Motorola Mobile Radios 
                        [2] => mobile [c.path] => mobile 
                        [3] => 2 [c.parentcatid] => 2 
                    )
                ) 
            ) 
            [1] => Array (
                [0] => 5 [c.id] => 5 
                [1] => Icom Radios [c.name] => Icom Radios 
                [2] => icom [c.path] => icom 
                [3] => 1 [c.parentcatid] => 1 
                [children] => Array ( 
                    [0] => Array (
                        [0] => 6 [c.id] => 6 
                        [1] => Icom Handheld Radios [c.name] => Icom Handheld Radios 
                        [2] => handheld [c.path] => handheld 
                        [3] => 5 [c.parentcatid] => 5 
                    ) 
                    [1] => Array ( 
                        [0] => 7 [c.id] => 7 
                        [1] => Icom Mobile Radios [c.name] => Icom Mobile Radios 
                        [2] => mobile [c.path] => mobile 
                        [3] => 5 [c.parentcatid] => 5 
                    ) 
                ) 
            ) 
            [2] => Array (
                [0] => 8 [c.id] => 8 
                [1] => Mics & Speakers [c.name] => Mics & Speakers
                [2] => mics-and-speakers [c.path] => mics-and-speakers 
                [3] => 1 [c.parentcatid] => 1
            ) 
            [3] => Array ( 
                [0] => 9 [c.id] => 9 
                [1] => Mounting Hardware [c.name] => Mounting Hardware 
                [2] => mounts [c.path] => mounts 
                [3] => 1 [c.parentcatid] => 1 
            ) 
            [4] => Array ( 
                [0] => 10 [c.id] => 10 
                [1] => Clips & Assorted [c.name] => Clips & Assorted 
                [2] => other [c.path] => other 
                [3] => 1 [c.parentcatid] => 1 
            ) 
        ) 
    ) 
    [1] => Array ( 
        [0] => 11 [c.id] => 11 
        [1] => Miscellaneous [c.name] => Miscellaneous 
        [2] => misc [c.path] => misc 
        [3] => 0 [c.parentcatid] => 0 
        [children] => Array (
            [0] => Array (
                [0] => 12 [c.id] => 12 
                [1] => LED Lightbars & Products [c.name] => LED Lightbars & Products 
                [2] => led [c.path] => led 
                [3] => 11 [c.parentcatid] => 11 
            ) 
        ) 
    ) 
)

现在,如果我在该4类别中有一个项目,它被认为是一个手持收音机,摩托罗拉收音机的孩子。在项目上,我存储了这个 ID as catid = '4'。我现在需要找到一种方法,将 4 分支上方的所有信息返回到第一个结果(收音机 -> 摩托罗拉 -> 手持设备 -> 此处的项目)。我更愿意从上到下按顺序列出它们,这样我就可以循环并/store/radios/motorola/handheld/item.html使用子 ID 作为起始键来构建项目路径。

这可能使用这种布局吗?提前致谢

标签: phparrayssorting

解决方案


除了子树之外,您还需要创建一个将记录 ID 映射到记录的数组,然后您可以从目标记录的 ID 向上遍历。

<?php
//Mock category records, would come from the DB in the real world
$categoryRecords = [
    ['id' => 1, 'title' => 'Radios', 'slug'=>'radios', 'parent_id' => 0],
    ['id' => 2, 'title' => 'Accessories', 'slug'=>'misc', 'parent_id' => 1],
    ['id' => 3, 'title' => 'Motorola', 'slug'=>'motorola', 'parent_id' => 1],
    ['id' => 4, 'title' => 'Handheld', 'slug'=>'handheld', 'parent_id' => 3],
    ['id' => 5, 'title' => 'Mobile', 'slug'=>'mobile', 'parent_id' => 3],
    ['id' => 6, 'title' => 'Level 3', 'slug'=>'level-3', 'parent_id' => 5],
    ['id' => 7, 'title' => 'Level 4', 'slug'=>'level-4', 'parent_id' => 6]
];

//Create an array that maps IDs to records
$idMap = [];

foreach($categoryRecords as $currRecord)
{
    $idMap[$currRecord['id']] = $currRecord;
}

/*
 * Now would be a good time to cache this map in something like Redis or Memcache so you don't have to pull
 * the whole category table during every request.
 */

/**
 * Return an array of parent category records for a given category ID
 * @param int $categoryId
 * @return array
 */
function findParentCategories($categoryId)
{
    global $idMap;

    $categories=[];

    while(array_key_exists($categoryId, $idMap))
    {
        $currParentId = $idMap[$categoryId]['parent_id'];
        $categories[] = $idMap[$categoryId];

        $categoryId = $currParentId;
    }

    $categories = array_reverse($categories);

    return $categories;
}

//ID of category requested
$requestedId = 3;

/*
 * Top-to-bottom list of parent categories
 */
$parentCategories = findParentCategories($requestedId);

推荐阅读