• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:PHP:ツリー構造をulとli要素に変換したい)

PHPでツリー構造をulとli要素に変換する方法

このQ&Aのポイント
  • PHPでツリー構造をulとli要素に変換する方法について説明します。
  • 配列と文字列をもとに、getWBSHtml関数を作成します。
  • getWBSHtml関数を使用することで、指定した親要素に対して子要素を生成するHTMLを出力することが可能です。

質問者が選んだベストアンサー

  • ベストアンサー
  • nag_mm
  • ベストアンサー率100% (1/1)
回答No.3

配列の各要素ごとに次のような連想配列を作成します。 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)
回答No.4

<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)
回答No.2

前後関係だけを見て処理するならこんな感じ。 ただし相関関係があっているかは検証しないので微妙ですね <?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% (1327/1804)
回答No.1

値が数字だけだと抽象的すぎて何をしたいのか解り辛いけど…。 関数の記述はこの際置いておいて、配列を多次元の連想配列にした方が処理しやすい様な気がします。 で、変数の $rootWBS には、その時々に応じて必要な連想配列のキー名を代入して、関数側から呼び出して処理する様にすれば割とスマートな感じになるんじゃないのかなあと思います。

すると、全ての回答が全文表示されます。

関連するQ&A

  • PHP ループ <li>~</li>の出力方法

    <?php $input_01 = file('list/001.txt'); echo '<ul>'."\n"; foreach( $input_01 as $value ){ $num++; echo "\t".'<li><a href="' .$value. '"><img src="' .$num. '.jpg" alt="" /></a></li>'."\n"; } echo '</ul>'."\n"; /* 1. list/001.txtにはURLが多数入っていると仮定します。上記の構文ですと、<ul>~</ul>の中に全てのURLが出力されます。   例えばこれを以下のように5つずつ順にURLを出力、同時に00001~00005.jpgとなるよう出力するには、どうのような方法が、 軽く、スマートな方法のでしょうか? <ul> <li>~</li> <li>~</li> <li>~</li> <li>~</li> <li>~</li> </ul> 2. echo '<ul>'."\n"; のように、シングル、ダブルクォートを同時に使用する事は、変でしょうか? 色々検索して試行錯誤しましたが、フリーズしてしまいました。ご回答よろしくお願いいたします。 */

    • ベストアンサー
    • PHP
  • htmlソースからアンカータグ内のURLを配列に

    お世話になっております。 file_get_contents()で取得したhtmlファイルのソースにある、アンカータグに設置されている、URLおよび、そのアンカータグに囲まれたテキストを取得して配列に収めたいと考えているのですが、いろいろと調べていても、思うような結果を出せずにいる状況です。 あるサイトにて、以下のようなソースがあり、これをヒントとしているものの、初めて目にする配列の中の配列?に戸惑い、その分解の仕方が分からず、またアンカータグ内に、target="_blank"などの記述があったりすると、配列に収めることが出来なかったりで、対処の仕方がwからずにいる状況です。 $html = ' <ul> <li><a href="http://www.yahoo.co.jp/">Yahoo!JAPAN</a></li> <li><a href="http://jp.msn.com/">MSN</a></li> <li><a href="http://www.google.co.jp/">Google</a></li> </ul> '; $pattern = '/<a href="([^"]+)">(.+?)<\/a>/is'; $match = array(); preg_match_all($pattern, $html, $match, PREG_SET_ORDER); var_export($match); echo "<br><br>"; print_r($match); 知識が乏しく、お恥ずかしいところと思うことろではありますが、アドバイスなど頂戴できれば幸いです。 お忙しいなか恐縮ですが、宜しくお願い申し上げます。

    • ベストアンサー
    • PHP
  • Smartyで添え字が全て文字列の多次元配列

    Smartyで添え字が全て文字列の多次元配列 いつもお世話になっております。 Smartyで添え字が全て文字列の多次元配列を表示したいと考えています。 ■■元データ■■ $menu_list = array( '魚' => array( 'サバ' => 'サバカレー', 'タイ' => 'タイカレー' ), '肉' => array( '豚肉' => 'ポークカレー', '牛肉' => 'ビーフカレー' ), '野菜' => array( 'キャベツ' => 'キャベツカレー', 'きゅうり' => 'きゅうりカレー' ) ); ■■期待する出力■■ <ul> <li>魚 <li>サバ/サバカレー<li> <li>サバ/サバカレー<li> </li> </ul> <ul> <li>肉 <li>豚肉/ポークカレー<li> <li>牛肉/ビーフカレー<li> </li> </ul> <ul> <li>野菜 <li>キャベツ/キャベツカレー<li> <li>きゅうり/きゅうりカレー<li> </li> </ul> 散々悩んだ挙句、Smarty側では当初次のようにしたところ、とりあえずはうまくいっています。 {foreach from=$menu_list key="key" item="item" name="loopName"} {if $smarty.foreach.loopName.iteration <= 3} {if $smarty.foreach.loopName.iteration == 1} <ul> <li>魚 {elseif $smarty.foreach.loopName.iteration == 2} <ul> <li>肉 {elseif $smarty.foreach.loopName.iteration == 3} <ul> <li>野菜 {/if} {foreach from=$menu_list.$key key="key" item="val"} <li>{$key}/{$val}</li> {/foreach} {/if} </li> </ul> {/foreach} 元データの内容は頻繁に変わるため、Smartyのテンプレートに添え字を直で書くのは 避けたいのですが、どうしたら良いのでしょうか。 できるだけPHP側で加工して、テンプレートはループで回すだけにしたいと考えています。 すみませんが、お知恵を貸していただけないでしょうか。 ・・・カレー食べたい。

    • ベストアンサー
    • PHP
  • 不要な配列を消したい

    2次元配列で、不要な要素を取り除きたいのですが良い方法が思い浮かばず、どうしたものかと悩んでいます。 一番初めと5番目を消したいのですが、preg_match で日付の2006にマッチしない要素をunsetしてみましたがうまくいきませんでした。 $data = array ( array('<br>'), array("2006 03 22", test), array("2006 03 23", test2), array("2006 03 25", test3), array('') ); $pattern = '/2006/'; foreach($data as $key => $value) { if(preg_match($pattern, $value[$key])) { unset($data[$key]); } } もし方法をご存知のかたおられましたらよろしくお願いいたします。

    • ベストアンサー
    • PHP
  • textより$$にはさまれた文字列を取得する方法

    初めて質問させていただきます。 windowsにて、phpプログラムでtxt形式の文より$$で囲まれた文字列を抽出したいのですが上手くいきません。 サンプルとして現在使用している文は以下の通りです。 電圧に関するオームの法則は $$V=RI$$ である。 抵抗に関するオームの法則は $$R=V/I$$ である。 電流に関するオームの法則は $$I=V/R$$ である。 作成したプログラムは以下の通りです。 <?php $in = "C:/equation.txt"; $fp = fopen("$in","r"); while(!feof($fp)){ $data = fgets($fp,1024); print $data; } $patttern = "\$\$(.*)\$\$"; preg_match_all("/".$patttern."/",$data,$array); $value_list = array_values($array); foreach($value_list as $key => $value){ print $key.") ".$value."\n"; } 現状ではテキストは正常に返ってくるのですが、配列がちゃんと帰ってきません。おそらくpreg_match_allの時点で上手く抽出出来ていないと思うのですが何がおかしいのか分かりません。 どなたかご指導のほどよろしくお願いします。

    • ベストアンサー
    • PHP
  • 文字と数字が混在する要素のsortについて

    お世話になっております。 javascript初心者です。 以下のような要素を時系列でsortするにはどうすればいいでしょうか? <ul> <li>テキストを時系列で並び替えたい 2011/05/15/19:00</li> <li>テキストを時系列で並び替えたい 2009/01/15/14:00</li> <li>テキストを時系列で並び替えたい 2010/05/15/19:00</li> </ul> liの中のテキストをArrayオブジェクトに代入して配列にした後 sortでどのような処理をすればいいのでしょうか? 例えば var myArray = new Array(); でmyArrayと言う配列オブジェクトにliのテキストを代入したときに myArray.sort(function(a,b) {return a-b;}); とすれば比較要素が単体数字の場合はソートできるのですが 文字と/など複合数字が混在しているとソートできません。

  • 正規表現の「^」と「$」がうまくいかない

    正規表現の「^」と「$」を使うとうまく働いてくれません。 あるデータの中の、行頭がhttpで始まる1行を取り出したいです。 あるデータ$dataを preg_match_all("/^http(.*?)$/",$data,$result); print_r($result); で出力すると、 ■結果 Array ( [0] => Array ( ) [1] => Array ( ) ) となり、うまくいきません。 preg_match_all("/http(.*?)\n/",$data,$result); やけでこんな感じにやったら、行頭から始まるhttp.....も行頭からはじまらないものもゲットしてすべて出力してくれてしまいます。 行頭から始まるものだけを出力するにはどうしたらいいでしょうか。 php5 UTF-8環境

    • ベストアンサー
    • PHP
  • smartyのforeachの使い方

    仮に$strが以下のような配列を持っている場合smartyのtpl側で 出力させたいのですがうまくいきません。 Array ( [0] => Array ( [id] => 1 [name] => 名前 [sub_id] => Array ( [0] => 12 [1] => 13 ) [sub_name] => Array ( [0] => あああ [1] => いいい ) [sub_cnt] => Array ( [0] => 5 [1] => 5 ) ) [1] => Array ( [id] => 1 [name] => 名前 ) ) sub_***は配列が存在するものとしないものがあります。 そしてtpl側は {foreach item=items from=$str} <ul id="side{$items.id}"> {foreach item=item from=$items} <li><a href="index.php?id={$item.sub_id}">{$item.sub_name} ({$item.sub_cnt})</a></li> {/foreach} </ul> {/foreach} とforeachを重ねてみたのですがsub_***の値が表示されない 状態です。 複雑な配列なのですがこの場合どうすればうまく表示させれるの でしょうか?

    • ベストアンサー
    • PHP
  • foreach のバグでしょうか。PHP 5.3.3 で悩んだところが

    foreach のバグでしょうか。PHP 5.3.3 で悩んだところがあります。 あるレコードが正規表現にマッチした場合、そのレコードに対して何らかの処理をするスクリプトを書いていました。 しかし思ったように動かず原因を調べました。結果、配列の値が変わっていることに気づきました。  ◇テスト用レコードの内容   http://www.yahoo.co.jp/   http://www.bing.com/   http://www.goo.ne.jp/   http://www.google.co.jp   http://d.hatena.ne.jp/  ◇先頭一致して欲しい文字列   http://www.google.co.jp/   http://www.bing.com/   http://www.youtube.com/  この場合、処理の対象は2件です。  私が書いたスクリプトでは3回マッチしてしまいます。  以下、テスト用に作ったスクリプトです。 <?php // URL のパターンを用意 (とりあえず以下の3パターン) $ar = array(); $ar['Google'] = array(  'URL' => 'http://www.google.co.jp/' ); $ar['Bing'] = array(  'URL' => 'http://www.bing.com/' ); $ar['YouTube'] = array(  'URL' => 'http://www.youtube.com/' ); // 先頭一致の正規表現にする foreach($ar as $key => &$value){  $value['regex'] = '/^' . preg_quote($value['URL'], '/') . '/'; } echo("URL の パターンを出力してみる/n"); print_r($ar); // テスト用 レコード $list = array(); $list[] = 'http://www.yahoo.co.jp/'; $list[] = 'http://www.bing.com/'; // match. $list[] = 'http://www.goo.ne.jp/'; $list[] = 'http://www.google.co.jp/'; // match. $list[] = 'http://d.hatena.ne.jp/'; // マッチするのは2回のみ...のはずが for($n = 0; $n < count($list); $n ++){  foreach($ar as $key => $value){   if(preg_match($value['regex'], $list[$n], $match)) echo("match.\n");  } } echo("もう一度 URL のパターンを出力してみる\n"); print_r($ar); echo("なぜか一番最後の配列の値が変わっている。\n"); ?>

    • ベストアンサー
    • PHP
  • PHPの多次元配列について

    HTMLでホームページを作れる以外はプログラムに関しほぼ素人です。 環境 XAMPP1.70(最新)にてアパッチなど一括ダウンロード PHP言語にて3×4の表で以下の数値を多次元配列にて作成しようと思っているのですが、当方初心者なもので、 以下のコード(細かい部分は省略しています)、特にforeachがネストになっている部分の処理の流れがいまいちよくわかりません ~~~~~~~~~~~~~~~~~~~~~~~~~ <table border=2> <th>都市名</th> <th>最高気温</th> <th>最低気温</th> <?php  $data=array( array("東京"32,25) array("名古屋",45,67) array("埼玉",32,67) array("大阪",86,34) ) foreach($data as $city){ print "<tr>"; foreach($city as $value){ print "<td>{$value}</td>"    ●1回目foreachからここまでの流れがいまいち分かりません } print "</tr>"; ?> ~~~~~~~~~~~~~~~~~~~~ 一つ目のforeachにて、配列$dataが指定されていますので外側の配列を処理していくと思うのですが、具体的にどういう順番で処理されていくのでしょうか。 またforeach()の中の"$cityが最終的に$valueに格納という形になっていますが、10~13行目のarray("東京",32,25)とどのような関係で処理されていっているのか教えていただけませんでしょうか。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
outlook2019受信トレイの表示
このQ&Aのポイント
  • outlook2019受信トレイの表示についての質問です。
  • ご利用の製品やメールのサービス、製品名・型番、接続方法などを教えてください。
  • お困りごとの詳細や表示される内容もお教えください。
回答を見る

専門家に質問してみよう