dousui8263 2012-11-08 11:50
浏览 23
已采纳

如何在PHP中使用连接字符串构建树?

I try to make a tree list in PHP from a hierarchy stored in a concatenated string in my mysql database

This my table :

Screenshot of table

and I'd like to reproduce something like this :

<ul>
  <li>
    <ul>
      <li></li>
      <li>
          <ul>
              <li></li>
              <li></li>
           </ul>
      </li>
      <li></li>
    </ul>
  </li>
  <li></li>
  <li></li>
</ul>

I know I have to use a recursive function I don't reach to do...

Maybe someone could help me

  • 写回答

2条回答 默认 最新

  • dongqi8114 2012-11-08 17:59
    关注

    code without comments

    see the usage and dataset section below to see what you need to pass and how to use these functions:

    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;
      }
    }
    


    code with comments and explanation

    The code to convert your items to a tree structure:

    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;
    }
    

    The code to convert the tree structure to a 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;
      }
    }
    

    dataset:

    /// 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'),
    );
    

    usage:

    /// Simple usage :) if a little complex explanation
    
    $tree = items_to_tree( $items );
    $html = tree_to_ul( $tree );
    
    echo $html;
    


    in the interests of codegolf ;)

    The following could replace my items_to_tree function -- however it isn't advised.

    $a = array();
    foreach($items as $i){
     eval('$a["'.str_replace('.','"]["',$i['hierarchy']).'"]=array("#item"=>$i);');
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?