我尝试使用存储在mysql数据库中的连接字符串中的层次结构在PHP中创建树列表
这是我的表:
我希望重现这样的事情:
<ul>
<li>
<ul>
<li></li>
<li>
<ul>
<li></li>
<li></li>
</ul>
</li>
<li></li>
</ul>
</li>
<li></li>
<li></li>
</ul>
我知道我必须使用我无法达到的递归函数...
也许有人可以帮助我
答案 0 :(得分:3)
请参阅下面的用法和数据集部分,了解您需要传递的内容以及如何使用这些功能:
function items_to_tree( $items ){
$array = array();
foreach( $items as $item ) {
$parts = explode('.', $item['hierarchy']);
$last = array_pop( $parts );
$cursor = &$array;
foreach ( $parts as $part ) {
if ( !is_array($cursor[$part]) ) {
$cursor[$part] = array();
}
$cursor = &$cursor[$part];
}
$cursor[$last]['#item'] = $item;
}
return $array;
}
function tree_to_ul( $tree ){
$html = $children = '';
foreach( $tree as $key => $item ){
if ( substr($key,0,1) == '#' ) continue;
$children .= tree_to_ul( $item );
}
if ( isset($tree['#item']) ) {
$html .= '<li>' . PHP_EOL;
$html .= '<em>' . $tree['#item']['menu_text'] . '</em>' . PHP_EOL;
$html .= ( $children ? '<ul>' . $children . '</ul>' . PHP_EOL : '' );
$html .= '</li>' . PHP_EOL;
return $html;
}
else {
return $children;
}
}
将项目转换为树状结构的代码:
function items_to_tree( $items ){
$array = array();
foreach( $items as $item ) {
/// split each hierarchy string into it's dot separated parts
$parts = explode('.', $item['hierarchy']);
/// pop off the last item of the array, we'll use this for assignment later
$last = array_pop( $parts );
/// create a reference to our position in the array we wish to fill out
$cursor = &$array;
/// step each hierarchy part and travel down the array structure,
/// just like you would if you typed an array path manually.
/// i.e. $array[$part][$part][...] and so on
foreach ( $parts as $part ) {
/// if at this point in the array, we don't have an array, make one.
if ( !is_array($cursor[$part]) ) {
$cursor[$part] = array();
}
/// ready for the next step, shift our reference to point to the next
/// $part in the array chain. e.g. if $cursor pointed to `$array[$part]`
/// before, after the next line of code the $cursor will point
/// to `$array[$oldpart][$part]`
$cursor = &$cursor[$part];
}
/// we popped the last item off the $parts array so we could easily
/// assign our final value to where the $cursor ends up pointing to.
/// starting with a hierarchy of '00001.00002.00003' would mean at this
/// point $cursor points to $array['00001']['00002'] and $last = '00003';
/// so finally we get $array['00001']['00002']['00003']['#item'] = $item;
$cursor[$last]['#item'] = $item;
/// use '#item' to keep our item's information separate from it's children.
}
/// return our built up array.
return $array;
}
将树结构转换为UL的代码:
function tree_to_ul( $tree ){
/// start with nothing
$html = $children = '';
/// step each item found in the current level of $tree
foreach( $tree as $key => $item ){
/// if the item's key starts with a # skip, these contain
/// our item's information and should not be treated as children
if ( substr($key,0,1) == '#' ) continue;
/// recurse this function so that we do the same for any child @ any level.
$children .= tree_to_ul( $item );
}
/// if at this level a #item has been set, use this item information to
/// add a title to our level. You could change this to add whatever info
/// from your original database item that you'd like.
if ( isset($tree['#item']) ) {
$html .= '<li>' . PHP_EOL;
$html .= '<em>' . $tree['#item']['menu_text'] . '</em>' . PHP_EOL;
$html .= ( $children ? '<ul>' . $children . '</ul>' . PHP_EOL : '' );
$html .= '</li>' . PHP_EOL;
return $html;
}
/// if there wasn't an item, just return the traversed children.
else {
return $children;
}
}
数据集:
/// I simplified your dataset to an array, this could easily be generated
/// from a database query. You could also convert my code so that you
/// don't have to pre-generate an array, and instead could process after
/// each fetch from the database.
$items = array(
array('hierarchy' => '00001', 'menu_text' => 'One'),
array('hierarchy' => '00002', 'menu_text' => 'Two'),
array('hierarchy' => '00002.00001', 'menu_text' => 'Three'),
array('hierarchy' => '00002.00002', 'menu_text' => 'Four'),
array('hierarchy' => '00002.00003', 'menu_text' => 'Five'),
array('hierarchy' => '00002.00004', 'menu_text' => 'Six'),
array('hierarchy' => '00003', 'menu_text' => 'Seven'),
array('hierarchy' => '00003.00001', 'menu_text' => 'Eight'),
array('hierarchy' => '00003.00001.00001', 'menu_text' => 'Nine'),
array('hierarchy' => '00003.00001.00002', 'menu_text' => 'Ten'),
array('hierarchy' => '00003.00001.00003', 'menu_text' => 'Eleven'),
array('hierarchy' => '00003.00002', 'menu_text' => 'Twelve'),
);
用法:
/// Simple usage :) if a little complex explanation
$tree = items_to_tree( $items );
$html = tree_to_ul( $tree );
echo $html;
以下内容可以取代我的items_to_tree
功能 - 但不建议这样做。
$a = array();
foreach($items as $i){
eval('$a["'.str_replace('.','"]["',$i['hierarchy']).'"]=array("#item"=>$i);');
}
答案 1 :(得分:1)
$refs = new stdClass();
//Assuming $data is the result array of your query to fetch the data.
foreach($data as $result)
{
$name = $result['hierarchy'];
$parent = substr($result['hierarchy'],0,strrpos($result['hierarchy'],'.'));
$thisref = &$refs->{$name};
foreach($result as $k => $v)
{
$thisref->{$k} = $v;
}
if ($parent == '') {
$tree->{$name} = &$thisref;
} else {
$refs->{$parent}->children->{$name} = &$thisref;
}
}
这将为您提供一个很好的对象,其中包含属性子节点中每个节点的子节点。
function drawUL($level){
echo '<ul>';
foreach($level as $li){
echo '<li>'.$li->label;
if(isset($li->children))drawUl($li->children);
echo '</li>';
}
echo '</ul>';
}
drawUl($tree);