如果你对问题的第二个问题感到困惑,请坚持下去,因为我不确定它是否真的有意义。
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并执行<h1>
,1.1使用<h2>
但是当涉及到4.1.x时,请打开<ul>
并为每个规则指定<li>
1}}。
为此,我认为最好的方法是选择数据,就像我最终得到的数组一样:
array( 4 =>
array( 4.1 =>
array( 4.1.1 => 'rule content')
)
);
然后我可以实现自己的深度并打开<ul>
标签,循环打印出那个深度的规则等。
解决这个问题的最佳方法是什么?我已经多年了,并且不知道从哪里开始说实话。我真的希望数据在同一个表中。我想我可以解决这个问题,如果他们都在不同的表格中,但我不知道这肯定会更容易。
我开始沿着这条路走下去:
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';
}
然后我意识到这只是单独处理每个规则条目,而我的解决方案需要某种“意识”它在规则中的位置,因此它可以知道何时打开标记(例如{ {1}})然后在它完成回显规则中可能存在的列表项时再次关闭它(例如<ul>
)
以下是上述数据表中所需输出的示例:
希望一些明亮的火花可以帮助你!0。引言
...
4。聊天
4.1。做和不做
4.1.1。做:
- 4.1.1.9礼貌
- 4.1.1.10耐心等待
- 4.1.1.11聪明
答案 0 :(得分:4)
假设您可以根据输入数据生成如下数组:
$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);
答案 1 :(得分:1)
如果想要以可能破坏各种样式规则的方式混合HTML和SQL,可以添加“ruledepth”列,然后在其上使用“CASE”,例如:
SELECT othercols,
CASE
WHEN ruledepth=0 THEN CONCAT('<h1>', ruleid, '</h1>')
WHEN ruledepth=1 THEN CONCAT('<h2>', ruleid, '</h2>')
WHEN ruledepth=2 THEN CONCAT('<li>', rileid, '</li>')
etc
END FROM XXX WHERE .... ORDER BY ruleid........
答案 2 :(得分:1)
稍微修改OP代码。
您可以将$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;
}
答案 3 :(得分:0)
我不确定这是否正是你所需要的,但也许它会给你一些想法。
首先,您可以通过执行以下操作来确定规则的“深度”:
$depth = count(explode('.',$rule_id));
这将在.
上拆分您的规则ID并创建一个数组。然后它计算数组中的项目以确定深度。