PHP – 如何访问深层数组的内容,动态构建它的路径
我试图在
PHP中构建一个分层数组,从使用闭包表存储的关系数据库内容.对于给定的结果,我将获得LEAF节点的完整路径,下面看起来像我的结果集.
1~root~根节点 1~根?根节点>>> 2~category1~第一类 1~根?根节点>>> 3~category2~第二类 1~根?根节点>>> 2~category1~第一类>>> 4~subCatOfCategory1~Cat 1的子类别 无论如何,那些是我的数据库结果.所以我想遍历它们并在PHP中构建一个层次结构,这样我就可以将它转换为JSON并在DOJO中呈现一棵树 因此,当我遍历每一行时,我正在构建一个叶子的“路径”,因为当元素是一个“叶子”时我只需要向树中添加一个元素……沿着这个想法,我决定将每个结果标记为,使用“>>>”作为分隔符,给我那个行中的节点.然后我遍历这些节点,用“?”标记每个节点,这给了我每个节点的属性. 所以,我有一个for循环来处理每个ROW,它基本上确定如果正在处理的节点不是叶子,则将它的ID添加到一个数组,该数组将跟踪到达将要处理的最终叶子的路径.然后,当我最终到达LEAF时,我可以调用一个函数来插入一个节点,使用我沿途编译的PATH. 希望一切都有意义..所以我已经包含了下面的代码.考虑上面的第二个结果.当我处理完整个结果并即将调用函数insertNodeInTreeV2()时,数组如下所示… $fullTree是一个包含1个元素的数组,索引为[1] $pathEntries是一个只有一个元素的数组,(1).这意味着要插入的LEAF节点的PATH是节点[1],它是根节点. $nodeToInsert是一个包含四个元素的数组:ID(2),NAME(category1),Description(First Category),CHILDREN(空数组) $treeRootPattern是一个STRING,它包含我用来存储整个数组/树的变量名,在本例中是“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调试器中的新Expression中,它也会向我显示一个空数组,这是有道理的,因为它位于$fullTree [1] [‘CHILDREN’]中 但相反,运行时告诉我以下错误……
任何有关这方面的帮助都将非常感激……如果你有更好的方法让我从我描述的结果集中得到我想要构建的分层数组,我会急于采用更好的方法. 更新添加调用上述功能的代码 – 用于循环过程的数据库结果行,如上所述 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~根节点,如果还插入1~root~根节点>>> 2~category1~First类别. 如果节点是路径的最后一个节点,则只能通过创建节点来更改此设置.路径的长度是count($parts),您可以计算内部foreach循环中的哪个级别. 我希望这是你想要的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |