• 締切済み

phpでツリー表示

表題の通り、phpをもちいてツリー表示をしたいと思っています。 そこで、下記のコードの実行結果は以下の通りなのですが、 【このように実行結果を変えたい】のように表示したいと考えています。 どのようにコードを書きかえれば、実行できるでしょうか? 【コード】 <?php function put_tree($no, $line, $broths, $childs, $texts) { echo '<span class="line">' . $line . '</span>'; echo '▼[' . $no . ']' . $texts[$no] . '<br>'; $line = preg_replace('/├$/', '│', $line); $line = preg_replace('/└$/', ' ', $line); $no = isset($childs[$no]) ? $childs[$no] : 0; while ($no > 0) { $tail = $broths[$no] ? '├' : '└'; put_tree($no, $line . $tail, $broths, $childs, $texts); $no = $broths[$no]; } } ?> <html> <head> <title>ツリー表示</title> <style> .line { font-family: "MS ゴシック", monospace; } </style> </head> <body> <?php $logs = array( array(1, 0, 'あああああ'), //記事番号・親記事番号・記事内容 array(2, 1, 'いいいいい'), array(3, 1, 'ううううう'), array(4, 2, 'えええええ'), array(5, 3, 'おおおおお'), array(6, 3, 'かかかかか'), array(7, 0, 'ききききき'), array(8, 6, 'くくくくく'), array(9, 8, 'けけけけけ'), array(10, 7, 'こここここ') ); $roots = array(); $broths = array(); $childs = array(); $texts = array(); foreach ($logs as $log) { list($no, $pno, $text) = $log; if ($pno == 0) { $roots[] = $no; } else { $broths[$no] = isset($childs[$pno]) ? $childs[$pno] : 0; $childs[$pno] = $no; } $texts[$no] = $text; } rsort($roots); foreach ($roots as $root) { put_tree($root, '', $broths, $childs, $texts); } ?> </body> </html> 【実行結果】 ▼[7]ききききき └▼[10]こここここ ▼[1]あああああ ├▼[3]ううううう │├▼[6]かかかかか ││└▼[8]くくくくく ││ └▼[9]けけけけけ │└▼[5]おおおおお └▼[2]いいいいい  └▼[4]えええええ 【このように実行結果を変えたい】 ▼[1]あああああ ├▼[3]ううううう │├▼[6]かかかかか ││└▼[8]くくくくく ││ └▼[9]けけけけけ │└▼[5]おおおおお └▼[2]いいいいい  └▼[4]えええええ ▼[7]ききききき └▼[10]こここここ

みんなの回答

  • agunuz
  • ベストアンサー率65% (288/438)
回答No.2

「こうしたい」と例示された内容では、どの順に処理するのかが読み取れません。親記事は古い順、レスは新しい順ということでしょうか? (例) <?php $logs = array( array(1, 0, 'あああああ'), //記事番号・親記事番号・記事内容 array(2, 1, 'いいいいい'), array(3, 1, 'ううううう'), array(4, 2, 'えええええ'), array(5, 3, 'おおおおお'), array(6, 3, 'かかかかか'), array(7, 0, 'ききききき'), array(8, 6, 'くくくくく'), array(9, 8, 'けけけけけ'), array(10, 7, 'こここここ') ); print '親記事、レスとも古い順<br>'; foreach ($logs as list($no, $oya, $kiji)) { if ($oya > 0) { continue; } print $no . $kiji . '<br>'; listchild($logs, $no); } function listchild($logs, $parent) { $ct = 0; foreach ($logs as list($no, $oya, $kiji)) { if ($oya !== $parent ) { continue; } if ($ct++ == 0) { print '<ul>'; } print '<li>' . $no . $kiji . '</li>'; listchild($logs, $no); } if ($ct > 0) { print '</ul>'; } } print '<hr>'; print '親記事は古い順、レスは新しい順<br>'; // おそらくはこちらですかね? foreach ($logs as list($no, $oya, $kiji)) { if ($oya > 0) { continue; } print $no . $kiji . '<br>'; listchilds($logs, $no); } function listchilds($logs, $parent) { $ct = 0; for ($i = count($logs) - 1; $i >= 0; $i--) { list($no, $oya, $kiji) = $logs[$i]; if ($oya !== $parent ) { continue; } if ($ct++ == 0) { print '<ul>'; } print '<li>' . $no . $kiji . '</li>'; listchilds($logs, $no); } if ($ct > 0) { print '</ul>'; } }

全文を見る
すると、全ての回答が全文表示されます。
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

どういうコンセプトか分りませんが >rsort($roots); でわざわざ順番を逆順にしてる個所をやめれば済む話では?

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

関連するQ&A

  • クッキーに配列データを

    こんばんは。お世話になってます。 クッキーに配列データを保存したく、調べながら試行錯誤を繰り返していますが行き詰まってしまい、 アドバイスを頂戴できればと投函させて頂きます。 やりたいことは、掲示板にて書き込まれた内容をDBで管理しているのですが、各スレッドごとに1つのファイル(ページ)にて 呼び出しており、ページを閲覧した際、過去に1度でも閲覧した内容はカウント(訪問者数)せず、初めて閲覧した時のみ カウントするといった内容にしたいのですが、DBに登録されているデータも複数あることから、 DBに登録されているデータの連番を、配列データ(クッキー名:view)としてクッキーに登録しようと 考えるところまで至っていますが、うまく登録することが出来ずにいる次第です。 他にもっと適切なやり方があったら、そのご意見も頂戴したいのですが、以上のような考え方の場合、以下のスクリプトにおいて、 どこが不適切なのかをご指摘いただければ幸いにおもっております。 以下が、現在テスト中のスクリプトです。 $view_array = $_COOKIE["view[]"]; $view_array = unserialize(base64_decode($view_array)); //print_r($view_array); if(isset($_COOKIE["view[]"])){ if(!in_array($pno, $view_array)){ $count = $count+1; $sql = "update name set count = $count where no ='$pno'"; mysql_query($sql); $view_array[] = $pno; setcookie("view[]", base64_encode(serialize($view_array)), time() + 60*60*24*360, "/"); } }else{//クッキーに該当する配列がなかった場合 $count = $count+1; $sql = "update name set count = $count where no ='$pno'"; mysql_query($sql); $view_array = array($pno); setcookie("view[]", base64_encode(serialize($view_array)), time() + 60*60*24*360, "/"); } 以上、お忙しいなか恐縮ですが、宜しくお願いいたします。

    • ベストアンサー
    • PHP
  • whileとarrayについて

    下記のコードで、出力した結果、データベースには4つのデータがあるにもかかわらず、最新の4つ目のデータしか表示されません。 ツリー構造で、データをすべて出力することが第一目的なのでこの形にこだわりたいと思っています。 どのようにすれば解決するでしょうか? 【コード】 <?php $sql = "SELECT * FROM thread_detail WHERE thread_id = $id"; $date = mysql_query($sql,$link); while ($post = mysql_fetch_assoc($date)) { $logs = array( array($post['thread_detail_id'], $post['parent_thread_detail'], $post['body'],'<a href ="thread.php?id='.$post['thread_id'].'">編集</a>', '削除'), ); } foreach ($logs as list($no, $oya, $kiji, $edit, $delete)) { if ($oya > 0) { continue; } print $no .'<br>'. $kiji . $edit . $delete . '<br>'; listchild($logs, $no); } function listchild($logs, $parent) { $ct = 0; foreach ($logs as list($no, $oya, $kiji, $edit, $delete)) { if ($oya !== $parent ) { continue; } if ($ct++ == 0) { print '<nobr>&nbsp<ul></nobr>'; } print '<li>' . $no .'<br>'. $kiji . $edit . $delete . '<br>' . '</li>'; listchild($logs, $no); } if ($ct > 0) { print '&nbsp</ul>'; } } ?>

    • ベストアンサー
    • PHP
  • 変数について

    下記のような例の場合は、どのようにすれば【意図した結果】のようになりますでしょうか? 【コード】 <?php $post['thread_id'] = 1; $thread_id = $post['thread_id']; $logs = array( array(1, 0, $post['thread_id'], '<a href ="thread.php?id=$thread_id">編集</a>', '削除'), ); foreach ($logs as list($no, $oya, $kiji, $edit, $delete)) { if ($oya > 0) { continue; } print $no .'<br>'. $kiji . $edit . $delete . '<br>'; listchild($logs, $no); } function listchild($logs, $parent) { $ct = 0; foreach ($logs as list($no, $oya, $kiji, $edit, $delete)) { if ($oya !== $parent ) { continue; } if ($ct++ == 0) { print '<nobr>&nbsp<ul></nobr>'; } print '<li>' . $no .'<br>'. $kiji . $edit . $delete . '<br>' . '</li>'; listchild($logs, $no); } if ($ct > 0) { print '&nbsp</ul>'; } } 【結果:編集のリンク先】 「thread.php?id=$thread_id」 【意図した結果】 「thread.php?id=1」

    • ベストアンサー
    • PHP
  • 携帯絵文字変換スクリプトで20個目以降がエラーに

    ただいま1つのソースで3キャリアに対応した携帯サイトを作成しております。 絵文字を表示させるために、HTMLタグボードさんで配布されている「携帯絵文字変換スクリプト 3キャリア対応」 http://www.dspt.net/tools/emoji/ (フリーソフト/改変・改造自由)を組み込んでみたのですが、 下のようなエラーになってしまいました。 絵文字が19個目までは正常に表示されて、20個目以降がエラーになってしまいます。 (テストの為にHTMLファイルの<BODY></BODY>内に同じ絵文字だけを20個以上並べたところ、絵文字の種類にかかわらず20個目から[an error occurred while processing this directive]となってしまいます。) HTMLファイルをPCから開いても携帯から開いても上記と同じ現象が起こるので、もしかしたら携帯絵文字変換スクリプトの中に表示数の上限に関係した記述があるのではと思ったのですが、php初心者のためスクリプトを見ても原因がわかりませんでした。 もし原因の分かる方がいらっしゃったら、ぜひ教えていただければと思います。 どうぞよろしくお願いいたします。 ■絵文字変換スクリプト本体 trans.php <?php //┌───────────────────────────────── //│ [ EMOJI TRANS Ver2.3] //│ trans.php - 2008/06/15 //│ Copyright (C) DSPT.NET //│ webmaster@dspt.net //│ http://www.dspt.net/ //└───────────────────────────────── /********************** 初期設定 ***********************/ //絵文字変換表 $emoji_data = "emojix.csv"; //入力値取得 $num = $_GET["emoji"]; //PC用絵文字格納フォルダ $img_dir = "/php/emoji/images/"; //ドコモ→au絵文字自動変換利用(on:1 off:0) $ie = "1"; /********************** 以下からは改変しないほうが無難 ***********************/ //変換表を配列に格納 $emoji_array = array(); $emoji_array[] = ""; $contents = @file($emoji_data); foreach($contents as $line){ $line = rtrim( $line ); $emoji_array[] = explode(",", $line); } function encode($data) { $data = mb_convert_encoding($data, "SJIS", "auto"); return $data; } //携帯UA取得 $agent = $_SERVER["HTTP_USER_AGENT"]; //携帯端末のユーザエージェントを判定 function mobile($data){ if(preg_match("/^DoCoMo\/[12]\.0/i", $data)) { return "i";// i-mode } elseif(preg_match("/^(J\-PHONE|Vodafone|MOT\-[CV]980|SoftBank)\//i", $data)) { return "s";// softbank } elseif(preg_match("/^KDDI\-/i", $data) || preg_match("/UP\.Browser/i", $data)) { return "e";// ezweb } elseif(preg_match("/^PDXGW/i", $data) || preg_match("/(DDIPOCKET|WILLCOM);/i", $data)) { return "w";// willcom } elseif(preg_match("/^L\-mode/i", $data)) { return "l";// l-mode } else { return "p";// pc } } //携帯キャリアに合わせて絵文字を出力 function emoji($data) { global $agent,$emoji_array,$img_dir,$ie; if(preg_match("/[0-9]{1,3}/", $data) && is_numeric($data) && 0 < $data && $data < 253) { switch(mobile($agent)){ case "i"; $put = $emoji_array[$data][1]; break; case "e"; if (preg_match("/[^0-9]/", $emoji_array[$data][2])) { $put = $emoji_array[$data][2]; } elseif ($ie > 0) { $put = $emoji_array[$data][1]; // Display such the icons that ezserver transformed as docomo i-emoji. } else { $put = "<img localsrc=\"".$emoji_array[$data][2]."\" />"; } break; case "s"; if (preg_match("/^[A-Z]{1}?/", $emoji_array[$data][3])) { $put = "\x1B\$".encode($emoji_array[$data][3])."\x0F"; } else { $put = encode($emoji_array[$data][3]); } break; case "p"; $put = "<img src=\"".$img_dir.$emoji_array[$data][0].".gif\" width=\"12\" height=\"12\" border=\"0\" alt=\"\" />"; break; } echo $put; } else { echo "[Error!]\n"; } } //処理 emoji($num); ?>

    • ベストアンサー
    • PHP
  • ファイルの内容の表示

    実行時のコマンドライン引数で指定したファイルの内容を、行番号付きで画面に表示するプログラムを作る という問題です。ヒントも与えられています。 行番号付きの表示、コマンドライン引数の利用。両者を組み合わせればできるはずだ >  main関数の引数にargcとargvを指定して、コマンドライン引数をファイル名として利用する。キーボード入力を促す文(プロンプト)や改行チェックは不要なので書かないこと >  コマンドライン引数が指定されない場合は、メッセージを表示してプログラムを終了 >  ファイルの内容を画面表示する処理は、ユーザー定義関数put_file_contentsに記述する。仮引数には文字型のポインタ変数をひとつ指定し、ファイル名を受け渡せるようにする。put_file_contents自体の型は整数型(int)で、正常終了なら返り値0を返すこと。 行番号付きのプログラム#include<stdio.h> > int put_file(char *filename); > > int main() > { > char line[50]; > char *ptr; > > printf("ファイル名を入力:"); > fgets(line,sizeof(line),stdin); > ptr = line + strlen(line) - 1; > if(*ptr == '\n') { > *ptr = '\0'; > } > > put_file(line); > > return 0; > } > > int put_file(char *filename) > { > FILE *fp; > char buf[100]; > int line_no; > > fp = fopen(filename,"r"); > if (fp == NULL){ > printf("%sを開けません\n",filename); > return 1; > } > line_no = 1; > while (fgets(buf,sizeof(buf),fp) != NULL){ > printf("%3d: ",line_no); > printf("%s",buf); > line_no++; > } > fclose(fp); > > return 0; > } で、コマンドライン引数のプログラムは#include<stdio.h> void write_key_inputs(char *filiname); int main(int argc, char *argv[1]) { write_key_inputs(argv[1]); return 0; } void write_key_inputs(char *filename) { FILE *fp; char buf[100] ; fp = fopen(filename,"w"); while(fgets(buf, sizeof(buf),stdin) != NULL) { fputs(buf, fp); } fclose(fp); return ; } です。これらを組み合わせて少しいじると出来るみたいなのですが、できていません。ちなみに私が考えたプログラムは #include<stdio.h> int put_file_contents(char *filename); int main(int argc,char *argv[]) { int i; if(argc == 1){ printf("コマンドライン引数がありません\n"); return 1; } for(i = 0;i<argc;i++) printf("argv[%d]は「%s」です\n",i,argv[i]); put_file(i); return 0; } int put_file(char *filename) { FILE *fp; char buf[100]; int line_no; fp = fopen(filename,"r"); line_no = 1; while (fgets(buf,sizeof(buf),fp) != NULL){ printf("%3d: ",line_no); printf("%s",buf); line_no++; } fclose(fp); return 0; } です。コマンドライン引数は表示されるのですが、行番号が表示されません。どうしたらいいでしょうか??

  • Perl内でPHPの出力結果を表示したい

    Perl製のCGI内で、PHP製のランダムバナー表示CGIを呼ぼうとしたのですが、下記のようなエラーが出てしまいました。 いろいろ試行錯誤したのですが、お手上げです。 どのように修正したらよいでしょうか? なお、ランダムバナー表示CGI 単体だけを実行したときは、正常に表示されています。 [index.cgi]  #!/usr/local/bin/perl  print "Content-type: text/html\n\n";  print "<HTML>\n<BODY>\n\n";  $ImgFileName="./ad.php";  open(IN, "$ImgFileName |");  while (<IN>) {    $str=$str.$_;  }  close(IN);  print $str; [ad.php]  <?php  $_1 = ('<img src="http://example.jp/a.gif">');  $_2 = ('<img src="http://example.jp/b.gif">');  $img_arry = array("$_1","$_2");  srand((double)microtime()*1000000);  $num =array_rand($img_arry);  $image = $img_arry[$num];  echo "$image";  ?> [表示された内容] ./ad.php: ?php: No such file or directory ./ad.php: line 2: syntax error near unexpected token `('' ./ad.php: line 2: `$_1 = ('【a.gifの画像】);'

  • ヒープの質問です(難易度高)

    ランダムな数15個(=1+2+4+8個)を 二分ヒープに並べ替える次のようなプログラムを作りました。 require 'HeapByArray.rb' array=Array.new(); i=0; puts("Before") while(i<15) i+=1; array[i]=rand(100); print(" "+array[i].to_s) end puts(" "); queue=HeapByArray::new i=0; while(i<15) i+=1; queue.enqueue(array[i]); end puts("After") i=0; while(i<15) i+=1; array[i]=queue.dequeue(); print(" "+array[i].to_s); end puts(); たとえばデータが [1,11,14,9,5,2,15,7,6,4,12,10,8,3,13]ならば [15,14,13,12,11,10,9,8,7,6,5,4,3,2,1]といった風に 並べ替えられます。実行結果は Before 1,11,14,9,5,2,15,7,6,4,12,10,8,3,13 After 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1 となります。 そこでこの実行結果表示をツリーの表示、つまり □□□8 □□12 □□□7 □14 □□□6 □□11 □□□5 15 □□□4 □□10 □□□3 □13 □□□2 □□9 □□□1 (□部分は空白です。ここで質問記事を投稿するときになぜか空白は無視されてしまうので□にしました。) という風になるように改良したいのですが何をすればよいでしょうか? 詳しい方、よろしくお願いいたします。

    • ベストアンサー
    • Ruby
  • PHP / MySQL / クエリ実行

    【概要】 PHPからMySQLへのクエリを実行したいのですが、結果が返りません。 【環境】 CentOS5 [PHP5] sakuraインターネット レンタルサーバ スタンダートプランです。 参考:http://www.sakura.ne.jp/rentalserver/matrix.html 【ソース PHP】 ------------------------------------------------------------ $query =  mysql_query(' SET @i := 0; SET @ii := 0; SET @iii := 0; SET @iiii := 0; select `sys_no`,`day`,`counter`,(@iiii := @iiii +1)as `counter2` from (select `sys_no`,`name`,`day`,(@i := @i +1) as `counter` from TBL名 ORDER BY `day` DESC ) as aa where counter BETWEEN (select a.counter from (select `sys_no`,`day`,(@ii := @ii +1) as `counter` from TBL名 ORDER BY day DESC ) as a where sys_no =5) - 1 AND (select a.counter from (select `sys_no`,`day`,(@iii := @iii +1) as `counter` from TBL名 ORDER BY day DESC ) as a where sys_no =5) + 1 '); while ($row = mysql_fetch_array($query)) { 結果取得処理 } ------------------------------------------------------------ ・上記をPHPより実行しますと、「while~」の部分で結果が無いとエラーが返ります。 ・phpMyAdminから直接クエリの部分のみを実行しますと、問題無く結果が返ります。 ・なお、クエリを簡単な一行程度の内容にしますと問題無く実行され、結果が返ります。例:select * from TBL名 ・また、上部にセットしている4つのSETを試しに削除した状態でPHPより実行しますと、結果は返りませんがエラーにはなりません。 以上、アドバイス頂戴できますでしょうか。 よろしくお願い致します。

    • ベストアンサー
    • PHP
  • phpをレンタルサーバにアップしてもうまくいかない

    Xamppのapacheを用いて localhostで次のプログラムを実行するとうまくいくのですが いざレンタルサーバにアップするとうまくいきません。 (whss.bizというphp,mysql対応サーバ) <?php if(isset($_POST['userid'])==True && isset($_POST['password'])==True) { $userid=$_POST['userid']; $password=$_POST['password']; $logFile=dirname(__FILE__).'/'.$userid.'.log'; if(file_exists($logFile)==False) { file_put_contents($logFile,$password); header("Location:backtotop.html"); } else { echo '<font color="red">このユーザーIDはすでに使われています。<br> 恐れ入りますが別のIDにして下さい。</font><br>'; } } ?> <html> <head> <title>新規登録画面</title> </head> <body> 新規ユーザー登録を行います。<br> 好きなユーザー名とパスワードをともに半角英数字で入力してください。<br> <form action="newuser.php" method="POST"> ユーザー名:<br> <input type="text" name="userid" size="25" /><br /> パスワード:<br> <input type="text" name="password" size="25"> <input type="submit" value="入力完了"> </form> </body> </html> これはユーザーIDとパスワードを登録するものなのですが、 Warning: file_put_contents(/home/brightsuger/public_html/brightsuger.log) [function.file-put-contents]: failed to open stream: Permission denied in /home/brightsuger/public_html/newuser.php on line 9 Warning: Cannot modify header information - headers already sent by (output started at /home/brightsuger/public_html/newuser.php:9) in /home/brightsuger/public_html/newuser.php on line 10 入力完了を押すと↑がでてきてしまいます。 1つ目のWarningにあるように サーバー上ではfile_put_contentsはできないのでしょうか? また、2つ目のWarningは意味がよくわかりません。

    • ベストアンサー
    • PHP
  • phpの日本語が□(四角)に文字化けします。

    PHPでテキストファイルの検索結果をソートして出力するスクリプトで文字化けが出て困って います。 テキストファイル------------------ 20101225|第二会議室|1200|1300|就職面接 20101225|第一会議室|1300|1400|打ち合わせ 20101225|第一会議室|1500|1600|テスト 20101225|第一会議室|0900|1000|会議 20101225|第一会議室|1200|1300|休憩 20101224|第一会議室|1200|1500|クリスマス会 スクリプト(抜粋)--------------------- //$_GET["year"]) = 2010; //$_GET["title"]) = "第一会議室"; //$_GET["month"] = 12; //$_GET["day"] = 25; foreach ($schedule_list as $lineno => $line) { list($schedule_date, $title, $str_time, $end_time, $body) = explode("|", $line); if ($schedule_date == date("Ymd", mktime(0, 0, 0, $_GET["month"], $_GET["day"], $_GET["year"])) && $title == $_GET["title"]) { //抽出結果を配列に格納 $data[] = array( 'sch_date'=>$schedule_date ,'title'=>"$title", 'str'=>$str_time, 'end'=>$end_time, 'body'=>"$body", 'no'=>$lineno); } } //開始時間(昇順)でソート //array_multisort($str, SORT_ASC, $end, $sch_date, $title, $body, $no, $data); foreach ($data as $key => $row) { $sch_date[$key] = $row['sch_date']; $title[$key] = $row['title']; $str[$key] = $row['str']; $end[$key] = $row['end']; $body[$key] = $row['body']; $no[$key] = $row['no']; } 表示結果(1)---------------------  print_r($data);  配列データの全体を表示すると、日本語も正しく表示されます。 Array ( [0] => Array ( [sch_date] => 20101225 [title] => 第一会議室 [str] => 1300 [end] => 1400 [body] => 打ち合わせ [no] => 1 ) 表示結果(2)---------------------  print_r($sch_date[0]); print_r($title[0]); print_r($str[0]); print_r($end[0]); print_r($body[0]); print_r($no[0]);  配列データの要素を指定して出力すると日本語が□になります。  20101225�13001400�1 以上、どなたかご教授下さい。 日付   会議室 開始時間 終了時間 使用者 20101225 �     1300    1400   �

    • ベストアンサー
    • PHP