Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从平面阵列和结构化ID构建阵列树_Php_Mysql_Html - Fatal编程技术网

Php 从平面阵列和结构化ID构建阵列树

Php 从平面阵列和结构化ID构建阵列树,php,mysql,html,Php,Mysql,Html,如果你被这个问题弄糊涂了,就不要发火,因为我不确定这个问题是否有意义 SELECT * FROM `rules` ORDER BY `Rank_1` , `Rank_2` , `Rank_3` , `Rank_4` ASC 收益率: 复制意大利面: 0 0 0 0 0 1 0 0 0 1 1 1 0 0 1.1 1 1 1 0 1.1.1 2 0 0 0 2 4 0 0 0 4 4 1 0

如果你被这个问题弄糊涂了,就不要发火,因为我不确定这个问题是否有意义

SELECT * FROM `rules` ORDER BY `Rank_1` , `Rank_2` , `Rank_3` , `Rank_4` ASC
收益率:

复制意大利面:

0   0   0   0   0
1   0   0   0   1
1   1   0   0   1.1
1   1   1   0   1.1.1 
2   0   0   0   2
4   0   0   0   4
4   1   0   0   4.1
4   1   1   0   4.1.1 
4   1   1   9   4.1.1.9
4   1   1   10  4.1.1.10 
4   1   1   11  4.1.1.11
然而,这些数据并不是完全以我需要的形式出现,以便对它做一些有用的事情

我想循环所有的规则,根据我的“深度”,做不同的事情。例如,我想取RuleID=0并执行
,1.1有
,但当涉及到4.1.x时,打开一个
,并给每个规则一个
  • 对于这一点,我认为最好的方法是选择数据,就像选择一个数组一样,我最终会得到:

    array( 4 =>
        array( 4.1 =>
            array( 4.1.1 => 'rule content')
        )
    );
    
    然后我可以意识到我的深度,打开一个
    标签,循环打印出该深度的规则等

    解决这个问题的最佳方法是什么?说实话,我已经做了很多年了,不知道从这里该怎么办。我真的希望数据在同一个表中。我想如果他们都在不同的表格中,我可能会解决这个问题,但我不确定这会更容易

    我沿着这条路线出发:

    foreach($m as $rule) {
        $depth = count(explode('.', $rule['ruleid']));
        switch($depth) {
            case 1:
                echo '<h1>'.$rule['content'].'</h1>';
                break;
            case 2:
                echo '<h2>'.$rule['content'].'</h2>';
                break;
            case 3:
                echo '<strong>'.$rule['content'].'</strong>';
                break;
        }
        echo '<br />\n';
    }
    
    foreach($m作为$rule){
    $depth=count(分解('.',$rule['ruleid']);
    交换机(深度){
    案例1:
    回显'.$rule['content'].';
    打破
    案例2:
    回显'.$rule['content'].';
    打破
    案例3:
    回显“”.$rule['content']”。;
    打破
    }
    回音“
    \n”; }
    然后我意识到这只是要单独处理每个规则条目,而我的解决方案需要某种“意识”它在规则中的位置,这样它就可以知道何时打开标记(例如
    ),然后在完成回显规则中可能存在的列表项(例如
    “不要这样做:
    • 这个
    • 或者这个

    以下是上述数据表中所需输出的示例:

    0.导言

    4.聊天 4.1.应做和不应做的事 4.1.1.应:
    • 4.1.1.9礼貌点
    • 4.1.1.10耐心点
    • 4.1.1.11聪明点

    • 我不确定这是否正是你所需要的,但也许它会给你一些想法

      首先,您可以通过以下操作确定规则的“深度”:

      $depth = count(explode('.',$rule_id));
      
      $data = array(
        '0'        => 'content 0',
        '1'        => 'content 1',
        '1.1'      => 'content 1.1',
        '1.1.1'    => 'content 1.1.1',
        '2'        => 'content 2',
        '4'        => 'content 4',
        '4.1'      => 'content 4.1',
        '4.1.1'    => 'content 4.1.1',
        '4.1.1.9'  => 'content 4.1.1.9',
        '4.1.1.10' => 'content 4.1.1.10',
        '4.1.1.11' => 'content 4.1.1.11',
      );
      

      这将在
      上拆分规则id并生成一个数组。然后对数组中的项目进行计数以确定深度。

      假设您可以从输入数据生成如下数组:

      $depth = count(explode('.',$rule_id));
      
      $data = array(
        '0'        => 'content 0',
        '1'        => 'content 1',
        '1.1'      => 'content 1.1',
        '1.1.1'    => 'content 1.1.1',
        '2'        => 'content 2',
        '4'        => 'content 4',
        '4.1'      => 'content 4.1',
        '4.1.1'    => 'content 4.1.1',
        '4.1.1.9'  => 'content 4.1.1.9',
        '4.1.1.10' => 'content 4.1.1.10',
        '4.1.1.11' => 'content 4.1.1.11',
      );
      
      然后,您可以使用以下方法将其转换为树状结构:

      // this will be our root node
      // it has no content, but a place for children
      $struct = array(
        'children' => array()
      );
      
      foreach ($data as $ruleID => $content) {
        //                 /\
        //                 ||
        //     for every rule id in the input data we start at
        //     the root
        //          ||
        //          \/
        $parent =& $struct;
      
        // we split $ruleID at the dot to get a path, which we traverse
        //            ||
        //            \/
        foreach (explode('.', $ruleID) as $val) {
      
          // for every entry in the path we
          // check if it's available in the current parent
          //    ||
          //    \/
          if (!isset($parent['children'][$val])) {
            // if not, we create an empty entry
            $parent['children'][$val] = array(
              'content' => '',       // no content
              'children' => array()  // no children
            );
          }
      
          //                         /\
          //                         ||
          // and then use either the new, or allready existent parent
          // as the new parent
          //      ||
          //      ||  mind the assignment by reference! this
          //      \/  is the most important part
          $parent =& $parent['children'][$val];
        }
      
        // after the whole path is traversed, we can
        // finally add our content
        //                    ||
        //                    \/
        $parent['content'] = $content;
      }
      
      print_r($struct);
      

      演示:

      如果您想将HTML与SQL混合在一起,可能会破坏各种样式规则,您可以添加一个“ruledepth”列,然后在其上使用“CASE”,例如:
      
      选择othercols,
      案例
      当ruledepth=0时,则为CONCAT(“”,ruleid“”)
      当ruledepth=1时,则为CONCAT(“”,ruleid“”)
      当ruledepth=2时,则为CONCAT(“
    • ”,rileid“
    • ”) 等 从XXX结束,其中……按规则ID订购。。。。。。。。

      对OPs代码进行轻微修改

      您可以将
      $rule['ruleid']
      添加到echo语句中,使其与所需的输出完全一致

      $hasList=false;
      foreach($m as $rule) {
          $depth = count(explode('.', $rule['ruleid']));
          // end previous list before starting with new rules
          if ($hasList && $depth<4) {
              echo '</ul>';
              $hasList=false;
          }
          switch($depth) {
              case 1:
                  echo '<h1>'.$rule['content'].'</h1>';
                  break;
              case 2:
                  echo '<h2>'.$rule['content'].'</h2>';
                  break;
              case 3:
                  echo '<strong>'.$rule['content'].'</strong>';
                  break;
              case 4:
                  // start list if not already started
                  if (!$hasList) {
                      echo '<ul>';
                      $hasList=true;
                  }
                  echo '<li>'.$rule['content'].'</li>';
                  break;
          }
          //echo "<br />\n";
      }
      // end last list
      if ($hasList) {
          echo '</ul>';
          $hasList=false;
      }
      
      $hasList=false;
      foreach(通常为百万美元){
      $depth=count(分解('.',$rule['ruleid']);
      //在开始新规则之前结束上一个列表
      
      如果($hasList&&$depthmaybe如果你解释了你想用这个来完成什么,我们会更好地帮助你。你能添加一个输入数据的可复制版本吗?手工编写这个只是为了让原型运行有点烦人;)太少的细节无法给出任何真正的答案。你也可以按RuleID排序,因为
      。“好了,你去Yoshi。不,我不能Imre,因为1<9和MySQL不能自然排序。也就是说,字符对字符,我已经做了什么来确定深度。但这条路线还不够。太好了!我想这样做,但我担心会浪费时间。”因为我不够好(很高兴您的代码会指出这一点,因为我不知道如何像您一样使用
      $struct
      )所以首先来这里。非常感谢,能够用PHP来做这件事比试图在多个表中处理数据要好得多。这是解释代码工作原理的正确地方吗?我非常感谢,我相信这会帮助别人。我在上一次尝试解决这个问题时(几个月前)确实提出了这个问题但我认为这不是最好的解决方案,因为我希望深度完全可变,甚至在某些情况下,在其他
        中也有
          等。很抱歉,我没有指定。