gpt4 book ai didi

PHP - 如何访问深层数组的内容,动态构建它的路径

转载 作者:可可西里 更新时间:2023-11-01 13:23:12 26 4
gpt4 key购买 nike

我正在尝试从使用闭包表存储的关系数据库内容在 PHP 中构建分层数组。对于给定的结果,我将获得 LEAF 节点的完整路径,下面看起来像我的结果集。

1~root~根节点

1~root~根节点>>>2~category1~第一类

1~root~根节点>>>3~category2~第二类

1~root~根节点>>>2~category1~第一类>>>4~subCatOfCategory1~Cat 1的子类

无论如何,这些是我的数据库结果。所以我想遍历它们并在 PHP 中构建一个层次结构,这样我就可以将它转换为 JSON 并在 DOJO 中呈现一棵树

因此,当我遍历每一行时,我正在构建一条通往叶子的“路径”,因为当元素是“叶子”时,我只需要向树添加一个元素......沿着这个想法我决定我会使用“>>>”作为分隔符标记每个结果,为我提供该行中的节点。然后我遍历这些节点,用“~”标记每个节点,这给出了每个节点的属性。

所以,我有一个 for 循环来处理每个 ROW,它基本上确定如果正在处理的节点不是叶子,则将它的 ID 添加到一个数组中,该数组用于跟踪到达最终叶子的路径处理。然后,当我最终到达 LEAF 时,我可以调用一个函数来插入一个节点,使用我一路编译的 PATH。

希望一切都有意义..所以我在下面包含了代码..考虑上面的第二个结果。当我处理完整个结果并准备调用函数 insertNodeInTreeV2() 时,数组如下所示...

$fullTree 是一个包含 1 个元素的数组,索引为 [1]该元素包含一个包含四个元素的数组:ID(1)NAME(root)Description(根节点) child (空数组)

$pathEntries 是一个只有一个元素 (1) 的数组。这意味着要插入的 LEAF 节点的 PATH 是通过节点 [1],即根节点。

$nodeToInsert 是一个有四个元素的数组:ID(2), NAME(category1), Description(First Category) ), CHILDREN(空数组)

$treeRootPattern 是一个字符串,其中包含我用来存储整个数组/树的变量名称,在本例中为“fullTree”。

private function insertNodeInTreeV2( array &$fullTree, array $pathEntries, array $nodeToInsert, $treeRootPattern )
{
$compiledPath = null;
foreach ( $pathEntries as $path ) {
$compiledPath .= $treeRootPattern . '[' . $path . '][\'CHILDREN\']';
}
// as this point $compiledPath = "fullTree[1]['CHILDREN']"
$treeVar = $$compiledPath;
}

因此,当我进行分配时,$treeVar = $$compiledPath;,我认为我将变量 $treeVar 设置为等于 $fullTree[1]['CHILDREN'](我已在调试器中验证为一个有效的数组索引)。即使我将 $compiledPath 的内容粘贴到 Eclipse 调试器中的新表达式中,它也会显示一个空数组,这是有道理的,因为它位于 $fullTree[1]['CHILDREN']

但是相反,运行时告诉我以下错误...

troller.php line 85 - Undefined variable: fullTree[1]['CHILDREN']

如有任何帮助,我们将不胜感激...如果您有更好的方法让我从我描述的结果集中获取我正在尝试构建的分层数组,我会很乐意采用更好的方法。

已更新以添加调用上述函数的代码——如上所述,FOR 循环处理数据库结果行

foreach ( $ontologyEntries as $entry ) {

// iterating over rows of '1~~root~~The root node>>>2~~category1~~The first category
$nodes = explode( '>>>', $entry['path'] );
$numNodes = count( $nodes ) - 1 ;

$pathToNewNode = null; // this is the path, based on ID, to get to this *new* node
for ( $level = 0; $level <= $numNodes; $level++ ) {

// Parse the node out of the database search result
$thisNode = array(
'ID' => strtok($nodes[$level], '~~'), /* 1 */
'NAME' => strtok( '~~'), /* Root */
'DESCRIPTION' => strtok( '~~'), /* This is the root node */
'CHILDREN' => array()
);

if ( $level < $numNodes ) { // Not a leaf, add it to the pathToThisNodeArray
$pathToNewNode[] = $thisNode['ID'];
}
else {
// processing a leaf, add it to the array
$this->insertNodeInTreeV2( $$treeRootPattern, $pathToNewNode, $thisNode, $treeRootPattern );
}

}

}

最佳答案

请参阅我在您的问题下方的评论以获得解释。

$paths = array(
"1~root~the root node",
"1~root~the root node>>>2~category1~First category",
"1~root~the root node>>>3~category2~Second category",
"1~root~the root node>>>2~category1~First category>>>4~subCatOfCategory1~SubCategory of Cat 1"
);

$tree = array();

foreach ($paths as $path)
{
$currentNode = &$tree;

$parts = explode(">>>", $path);

foreach ($parts as $part)
{
$node = explode("~", $part);

// create all nodes along this path
if (!isset($currentNode[$node[0]]))
{
$currentNode[$node[0]] = array(
"ID" => $node[0],
"NAME" => $node[1],
"DESCRIPTION" => $node[2],
"CHILDREN" => array(),
);
}

$currentNode = &$currentNode[$node[0]]["CHILDREN"];
}
}

var_dump($tree);

输出:

array
1 =>
array
'ID' => string '1' (length=1)
'NAME' => string 'root' (length=4)
'DESCRIPTION' => string 'the root node' (length=13)
'CHILDREN' =>
array
2 =>
array
'ID' => string '2' (length=1)
'NAME' => string 'category1' (length=9)
'DESCRIPTION' => string 'First category' (length=14)
'CHILDREN' =>
array
4 =>
array
'ID' => string '4' (length=1)
'NAME' => string 'subCatOfCategory1' (length=17)
'DESCRIPTION' => string 'SubCategory of Cat 1' (length=20)
'CHILDREN' => &
array
empty
3 =>
array
'ID' => string '3' (length=1)
'NAME' => string 'category2' (length=9)
'DESCRIPTION' => string 'Second category' (length=15)
'CHILDREN' =>
array
empty

该循环将创建路径中包含的所有节点,因此您无需插入 1~root~the root node,如果您还插入 1~root~根节点>>>2~category1~第一类

如果节点是路径的最后一个节点,您可以通过仅创建节点来更改此设置。路径的长度是 count($parts) 并且您可以计算您在内部 foreach 循环中所处的级别。

希望这就是你想要的。

关于PHP - 如何访问深层数组的内容,动态构建它的路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10020295/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com