人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHPの質問です。

以下のようなテキストファイルがあります。
※「.」や「..」は階層の深さです

.|メニュー1|1.php
..|メニュー1-1|1-1.php
...|メニュー1-1-1|1-1-1.php
..|メニュー1-2|1-2.php
.|メニュー2|2.php
..|メニュー2-1|2-1.php
.|メニュー3|3.php

これを、最終的にHTMLへリストとして出力したいのです。

<ul id="menu">
<li><a href="1.php">メニュー1</a>
<ul>
<li><a href="1-1.php">メニュー1-1</a>
<ul>
<li><a href="1-1-1.php">メニュー1-1-1</a>
</ul>
<li><a href="1_2.php">メニュー1-2</a>
</ul>
<li><a href="2.php">メニュー2</a>
<ul>
<li><a href="2-1.php">メニュー2-1</a>
</ul>
<li><a href="3.php">メニュー3</a>
</ul>

いろいろと調べてやってみたのですが難しくて・・・
階層の深さは一定ではありません。
SEOを考えて、最終的にHTMLにリストとして出力できることが希望です。
これをPHPで実現できるでしょうか?

また、上記とは関係なく、効率よく、かつ簡単にPHPでツリーメニューを実現できるようなものもご紹介いただければ助かります。

●質問者: indiana
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:HTML PHP SEO テキスト ファイル
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● kn1967
●10ポイント

phpファイルをサーバーにアップすると、そのサーバー内のファイルのリンクが一覧で表示できるツールを作成しています。 表示サンプル:http://dowdow.jp/sitemap.php URLの.. - 人力検索はてな

私が以前回答したものですがよろしければ改造してお使いください。

<?php 
//
//サイトマップ作成PHP
//
//----------定数宣言
 define("StartPath","./"); //探し始めるディレクトリ(末尾は/で終わっている事)
 define("MaxCall",2); //再帰呼び出しはメモリ(スタック)を食うので階層を決めておきます。
 define("ExtensionPattern","/\.(htm|html|php)$/"); //対象とするファイル拡張子
 define("SearchPattern","/<title>(.*)<\/title>/i"); //検索対象
//
//----------サブルーチン
 function dir_tree($path){
 static $count = 0; //この行は再帰呼び出し時には無視されますので階層が判ります。
 echo "<ul>$path\r\n";
 $count++; //ディレクトリ内に入る度に増分して現在深度を示す。
 if($count > MaxCall) {
 echo "<li>設定された階層深度限界のため、これ以下は表示されません</li>";
 }else{
 if(!is_dir($path)){ // $pathがディレクトリで無ければ何もしない。
 }elseif($handle = opendir($path)){
 // 
 // ディレクトリ内検索
 $index = false;
 $dir_array = array();
 $file_array = array();
 while(false !== $file = readdir($handle)){
 if($file == "." || $file == "..") {
 }elseif(is_dir($path . $file)) {
 array_push($dir_array, $file);
 }elseif($file == "index.html") {
 $index = true;
 }elseif(preg_match(ExtensionPattern,$file) == 1) {
 array_push($file_array, $file);
 }
 }
 closedir($handle);
 // 
 // ファイル名列挙
 sort($file_array); //ファイル名順にソート
 if($index == true){
 unshift($file_array, "index.html"); //配列の先頭にindex.htmlを附加
 }
 foreach($file_array as $file){
 if(preg_match(SearchPattern,join("",file($path . $file)),$match) == 1){
 echo "<li><a href=\"$path$file\">$match[1]</a>\r\n";
 }else{
 echo "<li><a href=\"$path$file\">$file</a>\r\n";
 }
 }
 // 
 // サブディレクトリ検索
 sort($dir_array); //ディレクトリ名順にソート
 foreach($dir_array as $dir){
 dir_tree($path . $dir . "/");
 }
 }
 }
 $count--; //呼び出し元に戻るので深度を戻す。
 echo "</ul>\r\n";
 }
//
//----------メインルーチン
echo"<font size=\"2\">\r\n";
dir_tree(StartPath); //サイトマップを作成したい階層
echo"</font>\r\n";
?>
◎質問者からの返答

ありがとうございます。

ディレクトリはもともとツリー構造なので簡単に作れるのですが、質問の例の場合、テキストから読み込むので閉じタグ(</ul>)の処理などが難しいんです・・・


2 ● tezcello
●10ポイント

こんなスクリプトでやってみました。

$str = <<<EOL
.|メニュー1|1.php
..|メニュー1-1|1-1.php
...|メニュー1-1-1|1-1-1.php
..|メニュー1-2|1-2.php
.|メニュー2|2.php
..|メニュー2-1|2-1.php
.|メニュー3|3.php

EOL;

$lines = preg_match_all('/(\.+)\|(.+)\|(.+\.php)/', $str, $arry);

$result = '<ul id="menu">'."\n";
$prev = 1;
for ($i=0; $i<$lines; $i++){
$level = strlen($arry[1][$i]);
if ($level > $prev){
$result .= "<ul>\n";
$prev = $level;
}else if ($level < $prev){
$result .= "</ul>\n";
$prev = $level;
}

$result .= '<li><a href="'.$arry[3][$i].'">'.$arry[2][$i]."</a>\n";

}

$result .= "</ul>\n";

print $result;

基になるテキストファイルを読み込む代りに、ヒアドキュメントで代入しています。

実際の状況に合わせて、file_get_contents() に置換えるか、別の関数で作成するなどして下さい。

◎質問者からの返答

ありがとうございます。

試してみました。

しかし、「メニュー1-2」の後に「</ul>」が足りないため、意図した階層構造にはなりませんでした・・・

(お恥ずかしいのですが、質問文の方も足りてなかったですね・・・すみません)


3 ● GEN111
●100ポイント

ちょっと手抜き気味なので空行や

階層 | メニュー名 | URL

のフォーマットになっていない行があるとおかしな出力になります。

$str = <<< ENDTEXT
.|メニュー1|1.php
..|メニュー1-1|1-1.php
...|メニュー1-1-1|1-1-1.php
..|メニュー1-2|1-2.php
.|メニュー2|2.php
..|メニュー2-1|2-1.php
.|メニュー3|3.php
ENDTEXT;

function create_list($text) {
 $rv = '' ;
 $level = 1 ;
 foreach (explode("\n", chop($text)) as $one) {
 list($d, $l, $u) = explode('|', $one) ;
 $d = strlen($d) ;
 if ($d == $level && $rv != '') $rv .= "</li>\n" ;
 while ($d > $level) {
 ++$level ;
 $rv .= "\n<ul>\n" ;
 }
 while ($d < $level) {
 --$level ;
 $rv .= "</li>\n</ul>\n</li>\n" ;
 }
 $rv .= '<li><a href="'.$u.'">'.$l."</a>" ;
 }
 $rv .= "</li>\n" ;
 while ($level > 0) {
 --$level ;
 $rv .= "</ul>\n" ;
 }

 return '<ul id="menu">'."\n".$rv ;
}

echo create_list($str) ;

終了タグ </li> が不必要なら該当部分は削除してください。

◎質問者からの返答

ス・バ・ラ・シ・イ!

完璧です。

こんな短いコードでできたなんて・・・

目から鱗です。

ありがとうございました。


4 ● Yota
●10ポイント

http://www.wiki.cc/php/?title=HTML_TreeMenu

pearライブラリのHTML_TreeMenuなら、PHPコード内もしくはXMLファイルからツリーを作れます。

◎質問者からの返答

ありがとうございます。

試してみたのですが、元のXMLを書くなら直接HTMLでリストタグで書くのと手間が同じなので・・・

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ