- ベストアンサー
PHPでツリー構造をulとli要素に変換する方法
- PHPでツリー構造をulとli要素に変換する方法について説明します。
- 配列と文字列をもとに、getWBSHtml関数を作成します。
- getWBSHtml関数を使用することで、指定した親要素に対して子要素を生成するHTMLを出力することが可能です。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
配列の各要素ごとに次のような連想配列を作成します。 Array ( [1] => Array ( [0] => 1.1 [1] => 1.2 [2] => 1.3 [3] => 1.4 [4] => 1.5 ) [1.1] => Array ( [0] => 1.1.1 ) [1.1.1] => Array ( ) [1.2] => Array ( [0] => 1.2.1 [1] => 1.2.3 ) [1.2.1] => Array ( [0] => 1.2.1.1 [1] => 1.2.1.2 [2] => 1.2.1.3 ) [1.2.1.1] => Array ( ) [1.2.1.2] => Array ( ) [1.2.1.3] => Array ( [0] => 1.2.1.3.1 ) [1.2.1.3.1] => Array ( ) [1.2.3] => Array ( ) [1.3] => Array ( ) [1.4] => Array ( ) [1.5] => Array ( [0] => 1.5.1 ) [1.5.1] => Array ( ) ) この配列を再帰的に処理すればOKです。全体はこんな感じです。 <?php $arrWBS = array("1", "1.1", "1.1.1", "1.2", "1.2.1","1.2.1.1","1.2.1.2","1.2.1.3","1.2.1.3.1","1.2.3", "1.3", "1.4", "1.5","1.5.1"); $rootWBS = "1"; // 連想配列の作成 $wbs_tree = array(); foreach($arrWBS as $data) { $wbs_tree[$data] = array(); if (preg_match("/^(.*)\.[^.]+$/", $data, $matches) > 0) { if(array_key_exists($matches[1], $wbs_tree)) { array_push($wbs_tree[$matches[1]], $data); } } } // HTMLタグの作成 function getWBSHtml($datas, $indent, $wbs_tree) { print(str_repeat(' ', $indent) . "<ul>\n"); foreach($datas as $name) { print(str_repeat(' ', $indent+2) . "<li>"); print($name); if (count($wbs_tree[$name]) > 0) { print("\n"); getWBSHtml($wbs_tree[$name], $indent+4, $wbs_tree); print(str_repeat(' ', $indent+2) . "</li>\n"); } else { print("</li>\n"); } } print(str_repeat(' ', $indent) . "</ul>\n"); } // 実行 getWBSHtml($wbs_tree[$rootWBS], 0, $wbs_tree); ?>
その他の回答 (3)
- JaneDue
- ベストアンサー率75% (263/350)
<li>の終了タグは省略可なので、閉じなくても良いなら再帰処理すれば楽です。ただしXHTMLだとアウト…。 function getWBSHtml($arrWBS,$rootWBS){ //必要な分だけ配列に $arr = preg_grep("/^$rootWBS\.(\d+)/",$arrWBS); echo "<ul>\n"; $ch = $flag = ''; foreach($arr as $val){ //更に下層があれば、重複判定flagつけて再帰。 if(preg_match("/^$rootWBS\.(\d+)\.(\d)/",$val,$arg)){ $ch = "$rootWBS.{$arg[1]}"; if($flag !== $ch){ $flag = $ch; getWBSHtml($arr,$ch);} //それ以外なら出力 }else{ echo "<li>$val\n"; } } echo "</ul>\n"; return; }
- yambejp
- ベストアンサー率51% (3827/7415)
前後関係だけを見て処理するならこんな感じ。 ただし相関関係があっているかは検証しないので微妙ですね <?PHP $arrWBS = array("1", "1.1", "1.1.1", "1.2","1.2.1","1.2.1.1","1.2.1.2","1.2.1.3","1.2.1.3.1","1.2.3", "1.3", "1.4", "1.5","1.5.1"); $space="\t"; foreach($arrWBS as $key=>$val){ $prev_num=$key==0?0:count(explode(".",$arrWBS[$key-1])); $this_num=count(explode(".",$val)); $next_num=count($arrWBS)<=$key+1?0:count(explode(".",$arrWBS[$key+1])); if($prev_num < $this_num){ $str.=str_repeat($space,$this_num -1); $str.="<ul>\n"; } $str.=str_repeat($space,$this_num); $str.="<li>"; $str.=$val; if($this_num == $next_num) $str.="</li>"; if($this_num >$next_num){ for($i=0;$i<$this_num -$next_num ;$i++){ if($i>0){ $str.="\n"; $str.=str_repeat($space,$this_num -$i); } $str.="</li>\n"; $str.=str_repeat($space,$this_num -1 -$i); $str.="</ul>"; } } $str.="\n"; } print "<pre>\n"; print htmlspecialchars($str); print "</pre>\n"; print ($str); ?>
- 4017B
- ベストアンサー率73% (1336/1814)
値が数字だけだと抽象的すぎて何をしたいのか解り辛いけど…。 関数の記述はこの際置いておいて、配列を多次元の連想配列にした方が処理しやすい様な気がします。 で、変数の $rootWBS には、その時々に応じて必要な連想配列のキー名を代入して、関数側から呼び出して処理する様にすれば割とスマートな感じになるんじゃないのかなあと思います。