我正在尝试在PHP中构建分层数组,从使用闭包表存储的关系数据库内容中获取。对于给定的结果,我将拥有到LEAF节点的完整路径,下面是我的结果集。
1~root~根节点
1~root~根节点>>>2~category1~第一个类别
1~root~根节点>>>3~category2~第二个类别
1~root~根节点>>>2~category1~第一个类别>>>4~subCatOfCategory1~Cat 1的子类别
这些是我的数据库结果。所以我想遍历它们并在PHP中构建一个层次结构,以便我可以将其转换为JSON并在DOJO中呈现树形图。
因此,当我遍历每一行时,我正在构建一个“路径”到叶子,因为只有在元素是“叶子”时我才需要将元素添加到树中... 沿着这样的思路,我决定使用“>>>”作为分隔符标记化每个结果,这样我就得到了在该行中的节点。然后,我循环遍历这些节点,通过“~”标记化每个节点,从而得到每个节点的属性。
因此,我有一个for循环来处理每一行,它基本上确定正在处理的节点是否不是叶子节点,如果不是,则将其ID添加到跟踪最终处理的叶子节点的路径的数组中。然后,当我最终到达LEAF时,我可以调用一个函数来插入一个节点,使用我沿途编制的PATH。
希望这一切都说得清楚...所以我在下面包含了代码.. 考虑上述第二个结果。当我处理完整个结果并即将调用insertNodeInTreeV2()函数时,数组如下所示... $fullTree是一个具有1个元素的数组,索引为[1]。该元素包含四个元素:
当我进行赋值$treeVar = $$compiledPath;时,我认为我正在将变量$treeVar设置为等于$fullTree [1] ['CHILDREN'](我已经在调试器中验证了这是一个有效的数组索引)。即使我将$compiledPath的内容粘贴到Eclipse调试器的新表达式中,它也会显示一个空数组,这是有道理的,因为这就是$fullTree [1] ['CHILDREN']所在的位置。
但实际上,运行时告诉我以下错误...
troller.php的第85行-未定义的变量:fullTree [1] ['CHILDREN']
任何关于此的帮助都将不胜感激...如果您有更好的方法让我从我描述的结果集中获取我正在尝试构建的分层数组,我将非常愿意采用更好的方法。
已更新以添加调用上述函数的代码-循环处理数据库结果的行,如上所述。
1~root~根节点
1~root~根节点>>>2~category1~第一个类别
1~root~根节点>>>3~category2~第二个类别
1~root~根节点>>>2~category1~第一个类别>>>4~subCatOfCategory1~Cat 1的子类别
这些是我的数据库结果。所以我想遍历它们并在PHP中构建一个层次结构,以便我可以将其转换为JSON并在DOJO中呈现树形图。
因此,当我遍历每一行时,我正在构建一个“路径”到叶子,因为只有在元素是“叶子”时我才需要将元素添加到树中... 沿着这样的思路,我决定使用“>>>”作为分隔符标记化每个结果,这样我就得到了在该行中的节点。然后,我循环遍历这些节点,通过“~”标记化每个节点,从而得到每个节点的属性。
因此,我有一个for循环来处理每一行,它基本上确定正在处理的节点是否不是叶子节点,如果不是,则将其ID添加到跟踪最终处理的叶子节点的路径的数组中。然后,当我最终到达LEAF时,我可以调用一个函数来插入一个节点,使用我沿途编制的PATH。
希望这一切都说得清楚...所以我在下面包含了代码.. 考虑上述第二个结果。当我处理完整个结果并即将调用insertNodeInTreeV2()函数时,数组如下所示... $fullTree是一个具有1个元素的数组,索引为[1]。该元素包含四个元素:
ID(1)
,NAME(root)
,Description(the root node)
和CHILDREN(empty array)
$pathEntries是一个具有一个元素(1)的数组。这意味着插入LEAF节点的路径是通过节点[1],也就是根节点。
$nodeToInsert是一个具有四个元素的数组: ID(2)
, NAME(category1)
, Description(First Category)
, CHILDREN(empty array)
$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的第85行-未定义的变量: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 );
}
}
}
$$treeRootPattern
)。如果您必须使用像$foo["bar"]
这样的字符串访问变量,则无法避免使用eval
。请参见 http://stackoverflow.com/questions/5065294/can-array-values-be-accessed-by-variable-variables - Basti$fullTree[1]['CHILDREN']
不是一个有效的变量名。只有$fullTree
是变量名称,其余部分由 PHP 解释。$fullTree[1]['CHILDREN']
的意思是:访问数组$fullTree
。进入索引1
指向的内存中。将其解释为数组。进入索引CHILDREN
指向的内存中。因此,首先根本不存在一个叫做$fullTree[1]['CHILDREN']
的变量,所以您无法通过变量变量来访问它。 :-) - Basti