ジョイ・ムラカミさんからの転載です。私は以前この記事を読んだことがありますが、非常にわかりやすく説明されています。
この問題は、製品分類、マルチレベルのツリー構造のフォーラム、メーリング リストなどの多くの場所で発生します。マルチレベル構造のデータを保存するにはどうすればよいでしょうか。
PHP アプリケーションでは、バックエンド データ ストレージは通常、大量のデータを保存し、効率的なデータ取得と更新サービスを提供できるリレーショナル データベースです。ただし、リレーショナル データの基本的な形式はフラットな構造である十字テーブルです。リレーショナル データベースに複数レベルのツリー構造を格納したい場合は、適切な変換作業を実行する必要があります。次に、私が見聞きしたことと実際の経験についてお話します。
階層データをフラット データベースに格納するには、基本的に 2 つの一般的な設計方法があります。
隣接リスト モデル
変更されたプレオーダー ツリー トラバーサル アルゴリズム
私はコンピューターを専攻しておらず、データ構造について何も学んでいないので、これら 2 つの名前を文字通りに翻訳しました。間違っている場合はお知らせください。
この 2 つは怖く聞こえるかもしれませんが、実際には非常に簡単に理解できます。ここでは、サンプル データとして単純な食品ディレクトリを使用します。 データ構造は次のようなものです。
食べ物
|
|---フルーツ
| |
||---赤
| |
| |--チェリー
| |
| |---黄色
| |
| |--バナナ
|
|---肉
|
|--牛肉
|
|--豚肉
英語がめちゃくちゃな PHP 愛好家をケアするために
: Food
フルーツ:フルーツ
赤:赤
チェリー:チェリー
黄色:黄色
バナナ:バナナ
肉: 肉
牛肉:牛肉
Pork: Pork
隣接リスト モデルは、
私たちがよく使用するモデルであり、多くのチュートリアルや書籍で紹介されています。各ノードに親ノードを追加して、このノードの親ノードを表すことにより、フラット テーブルを通じてツリー構造全体を記述します。この原則に従って、例のデータは次の表に変換できます。
+-----------------------+
| 親の名前 |
+----------------------+
| 食べ物 |
| 食べ物 |
| フルーツグリーン |
| グリーンペア |
| フルーツレッド |
| レッドチェリー |
| フルーツイエロー |
| 黄色 |
| 肉 |
| 牛肉 |
| 豚肉 |
+----------------------+
Pear が Green の子ノードであり、Green が Fruit の子ノードであることがわかります。ルート ノード「Food」には親ノードがありません。 この問題を簡単に説明するために、この例では名前のみを使用してレコードを表します。 実際のデータベースでは、各ノードを識別するために数値 ID を使用する必要があります。データベース テーブルの構造は、id、parent_id、name、description のようになります。このようなテーブルを使用すると、マルチレベル ツリー構造全体をデータベースに保存できます。
マルチレベルツリーの表示 このようなマルチレベル構造を表示する必要がある場合は、再帰関数が必要です。
<?php
// $parent は、表示したい子の親です。
// $level はツリーの奥に進むと増加します。
// 適切なインデントされたツリーを表示するために使用されます
。 function display_children($parent, $level)
{
// 親ノードのすべての子ノードを取得 $parent
$result = mysql_query('ツリーから名前を選択'.
'WHEREparent="'.$parent.'";');
// 各子ノードを表示します
。
while ($row = mysql_fetch_array($result))
{
// ノード名をインデントします
echo str_repeat(' ',$level).$row['name']."n"
//この関数を再度呼び出して、子ノードの子ノードを表示します
。display_children($row['name'], $level+ 1);
}
}
?>
構造全体のルート ノード (Food) でこの関数を使用すると、マルチレベル ツリー構造全体を出力できます。Food はルート ノードであり、その親ノードは空であるため、display_children('',0) を呼び出します。ツリー全体の内容が表示されます。
食べ物
フルーツ
赤
チェリー
黄色
バナナ
肉
牛肉
豚肉
フルーツの部分など、構造全体の一部だけを表示したい場合は、次のように呼び出すことができます
ほぼ同じメソッドを使用して、ルート ノードからのパスを知ることができます
。
任意のノードに。たとえば、Cherry のパスは「食べ物 > 果物 > 赤」です。 このようなパスを取得するには、最も深いレベル「Cherry」から開始し、クエリを実行してその親ノード「Red」を取得してパスに追加し、次に Red の親ノードをクエリしてパスに追加する必要があります。など、最上位の「Food」
<?php
まで続きます。
// $node は最も深いノードです
関数 get_path($node)
{
// このノードの親ノードをクエリします
$result = mysql_query('ツリーから親を選択'.
'WHERE name="'.$node.'";');
$row = mysql_fetch_array($result);
// 配列を使用してパスを保存します
$path = array();
// ルートノードでない場合は、上方向にクエリを続行します。
// (ルートノードには親ノードがありません)
if ($row['parent']!='')
{
// $node へのパスの最後の部分は名前です
// $node の親の
$path[] = $row['parent']
// このノードの親にパスを追加する必要があります。
// パスへ
$path = array_merge(get_path($row['parent']), $path);
}
// パスを返す
$path を返します。
}
?>
この関数を「Cherry」に使用すると: print_r(get_path('Cherry'))、次のような配列が得られます。
配列
(
[0] => 食べ物
[1] => フルーツ
[2] => 赤
)
希望の形式で印刷する方法はあなた次第です。
短所: この方法は非常にシンプルで、理解しやすく、使いやすいです。しかし、いくつかの欠点もあります。主な理由は、実行速度が非常に遅いこと、各ノードでデータベース クエリが必要であること、データ量が多い場合にはツリーを完成させるために多くのクエリが必要になることです。さらに、再帰的な操作が必要なため、再帰の各レベルである程度のメモリを占有する必要があるため、スペースの利用効率は比較的低くなります。
ここで、再帰計算を使用しない、より高速な別の方法を見てみましょう。これは、修正された事前注文ツリー走査アルゴリズムです。この方法を使用する場合は、上記の方法とは異なります。この方法は理解しやすいですが、この方法は再帰的なクエリ アルゴリズムを使用しないため、クエリの効率が高くなります。
まず次の方法で複数レベルのデータを紙に描きます。ルート ノード Food の左側に 1 を書き込み、次にツリーを下に進み、Fruit の左側に 2 を書き込み、ツリー全体に沿って移動を続けます。エッジは各ノードに番号を付けて左右にラベルを付けます。最後の数字は Food の右側にマークされた 18 です。 下の図では、番号が付けられたマルチレベル構造全体が表示されます。 (わかりませんか?指で数字を指して、1から18まで数えてみるとわかります。それでもわからない場合は、指の動きに注意してもう一度数えてください。)
これらの番号は、各ノード間の関係を示しています。「Red」の番号は 3 と 6 であり、「Food」1 ~ 18 の子孫ノードです。 同様に、左の値が 2 より大きく、右の値が 11 より小さいすべてのノードが「Fruit」2-11 の子孫であることがわかります。
1 食品 18
|
+----------------------------------------------+
| |
2 果物 11 12 肉 17
| |
+---------------------+ +---------------------+
| |
3 赤 6 7 黄 10 13 牛肉 14 15 豚肉 16
| |
4 チェリー 5 8 バナナ 9
このようにして、ツリー構造全体を左右の値を通じてデータベースに保存できます。続行する前に、以下の編集されたデータ表を見てみましょう。
+----------------------+-----+-----+
| 親の名前 |
+----------------------+-----+-----+
| 食品 1 |
| フルーツ 2 |
| フルーツレッド |
| レッドチェリー |
| フルーツイエロー |
| 黄色 |
| 食品 | 12 |
| 牛肉 | 13 |
| 豚肉 | 15 |
+----------------------+-----+-----+
注: SQL では「left」と「right」に特別な意味があるため、「lft」と「rgt」を使用して左右のフィールドを表す必要があります。 さらに、この構造ではツリー構造を表すために「親」フィールドは必要なくなりました。つまり、次のようなテーブル構造であれば十分です。
+-----------+-----+-----+
| 名前 |
+-----------+-----+-----+
| 食べ物 | 18 |
| フルーツ 2 |
| 赤 3 |
| チェリー 4 |
| 黄色 | 10 |
| バナナ |
| 肉 12 |
| 牛肉 13 |
| 豚肉 15 |
+-----------+-----+-----+
これで、データベースからデータを取得できるようになりました。たとえば、「Fruit」項目の下にあるすべてのノードを取得する必要がある場合は、次のようなクエリ ステートメントを作成できます。クエリでは次の結果が得られました。
+-----------+-----+-----+
| 名前 |
+-----------+-----+-----+
| フルーツ 2 |
| 赤 3 |
| チェリー 4 |
| 黄色 | 10 |
| バナナ |
+-----------+-----+-----+
ほら、たった 1 つのクエリでこれらすべてのノードを取得できます。上記の再帰関数のようにツリー構造全体を表示できるようにするには、そのようなクエリを並べ替える必要もあります。ノードの左辺値でソートします。
SELECT * FROM Tree WHERE lft BETWEEN 2 AND 11 ORDER BY lft ASC;
残りの問題は、階層的なインデントを表示する方法です。
<?php
関数display_tree($root)
{
//ルートノードの左右の値を取得
$result = mysql_query('SELECT lft, rgt FROM ツリー '.'WHERE name="'.$root.'";');
$row = mysql_fetch_array($result);
// 空の右辺値スタックを準備します。
$right = array();
// ルートポイントのすべての子孫ノードを取得します。
$result = mysql_query('SELECT name, lft, rgt FROM Tree '.
'.$row['lft']. AND ' 間の WHERE lft
$row['rgt'].' ORDER BY lft ASC;');
// 各行を表示します
while ($row = mysql_fetch_array($result))
{
// スタックが存在する場合のみスタックをチェックする
if (count($right)>0)
{
// ノードをスタックから移動する必要があるかどうかを確認します
while ($right[count($right)-1]<$row['rgt'])
{
array_pop($right);
}
}
// ノードの名前をインデントします。
echo str_repeat(' ',count($right)).$row['name']."n";
// このノードをスタックに追加します
$right[] = $row['rgt'];
}
}
?>
上記の関数を実行すると、再帰関数と同じ結果が得られます。ただ、データベース クエリが 2 つしかないため、新しい関数の方が高速になる可能性があります。 Cherry のパスを知りたい場合は、その左右の値 4 と 5 を使用してクエリを作成する方が簡単です。
SELECT 名前 FROM ツリー WHERE lft < 4 AND rgt > 5 ORDER BY lft ASC;
これにより、次の結果が得られます:
+----------------+
| 名前 |
+----------------+
| 食べ物 |
| フルーツ |
| 赤 |
+----------------+
それでは、特定のノードにはいくつの子孫ノードがあるでしょうか?それは非常に単純で、子孫の総数 = (rvalue - left value - 1)/2 子孫 = (right - left - 1) / 2 信じられませんか?自分で計算してください。この単純な式を使用すると、「フルーツ 2-11」ノードには 4 つの子孫ノードがある一方、「バナナ 8-9」ノードには子孫ノードがない、つまり親ノードではないことがすぐに計算できます。
すごいですよね?私はこの方法を何度も使ってきましたが、それでもやるたびに素晴らしい気分になります。
これは確かに良い方法ですが、左右の値を含むこのようなデータ テーブルを作成するのに役立つ方法はあるでしょうか?もう 1 つの関数を紹介します。この関数は、名前と親構造を持つテーブルを、左と右の値を持つデータ テーブルに自動的に変換します。
<?php
関数再構築_tree($parent, $left) {
// このノードの右の値は左の値 + 1 です
$right = $left+1
// このノードのすべての子を取得します。
$result = mysql_query('ツリーから名前を選択'.
'WHERE 親="'.$parent.'";');
while ($row = mysql_fetch_array($result)) {
// それぞれに対してこの関数を再帰的に実行します
// このノードの子
// $right は現在の正しい値です。
//rebuild_tree関数によってインクリメントされる
$right =再構築_tree($row['名前'], $right);
}
// 左の値が得られ、処理が完了しました。
// このノードの子も正しい値を知っています
mysql_query('UPDATE ツリー SET lft='.$left.', rgt='.
$right.' WHERE name="'.$parent.'";')
// このノードの正しい値 + 1 を返します。
$right+1 を返します。
}
?>
もちろん、この関数は再帰関数であり、左右の値
rebuild_tree('Food',1);
を使用してツリーを再構築するには、ルート ノードからこの関数を実行する必要があります。
この関数は少し複雑に見えますが、テーブルに手動で番号を付けるのと同じ機能で、3 次元の多層構造を左右の値を持つデータ テーブルに変換します。
では、このような構造のノードを追加、更新、削除するにはどうすればよいでしょうか? ノードを追加するには通常 2 つの方法があります。
元の名前と親構造を保持する方法、古い方法を使用してデータにデータを追加する方法、および各データが追加された後に再構築_tree 関数を使用して構造全体の番号を付け直す方法です。
より効率的なアプローチは、新しいノードの右側にあるすべての値を変更することです。たとえば、「Red」ノードの最後の子ノードとなる新しいフルーツ「Strawberry」を追加したいとします。まず、そのためのスペースを作る必要があります。 「赤」の右側の値を6から8に、「黄7~10」の左右の値を9~12に変更します。 類推して、新しい値のための余地を作りたい場合は、左右の値が 5 より大きいすべてのノードに 2 を追加する必要があることがわかります (5 は「Red」の最後の子ノードの正しい値です) )。 したがって、次のようなデータベース操作を実行します。
UPDATE Tree SET rgt=rgt+2 WHERE rgt>5;
UPDATE ツリー SET lft=lft+2 WHERE lft>5;
これにより、新しく挿入された値のためのスペースが解放され、その左側と右側の値はそれぞれ 6 と 7 になります。
INSERT INTO ツリー SET lft=6、rgt=7、name = です。 'Strawberry';
別のクエリを実行して見てみましょう。どうでしょうか?すぐ。
さて、マルチレベルのデータベース構造を 2 つの異なる方法で設計できます。どちらの方法を使用するかは完全に個人の判断に依存しますが、レベルが多く、数が多い構造の場合は 2 番目の方法を好みます。クエリの量は少ないが、データを頻繁に追加および更新する必要がある場合は、最初の方法の方が簡単です。
また、データベースがサポートしている場合は、データベース側でトリガー関数としてrebuild_tree()や領域解放操作を記述し、挿入や更新時に自動的に実行することもでき、より高い操作効率を実現できます。新しいノードの追加がより簡単になります。
クラス再帰メソッド
2004 年 5 月 31 日 - 午前 9 時 18 分にゲストによって投稿されました。
私は準再帰メソッドを使用してプログラムを書きましたが、これは記事の再帰メソッドとまったく同じではありません。それを xoops に移植する準備をしています。
http://dev.xoops.org/modules/xfmod/project/?ulink では
メモリ オーバーフローが発生しましたが、引き続き再帰的方法を使用する予定です。引き続き改善する必要がある
ので、議論する機会があれば幸いです
。あなたと一緒にCM。
» このコメントに返信
それとも 2 つの方法の比較ですか?
ゲストによる投稿、2004 年 3 月 17 日 - 午後 8 時 30 分。
私はこの記事を注意深く検討し、非常に有益であると感じましたが、もう一度考えてみると問題があると感じました (記憶のために、隣接ディレクトリ モードを再帰的方法、事前ソート トラバーサルと呼びます)ツリー アルゴリズム (私は事前ソート ツリー メソッドと呼んでいます):
1. 2 つの方法の最大の違いは、再帰ではクエリ時にスタックの使用が必要であるのに対し、事前ソート ツリーではノードの半分が必要であることです (挿入されたノード)更新のノードを更新するとき。ノードが多くて更新が頻繁な場合、事前にソートされたツリーの効率が低下し、ノードレベルが多い場合は再帰の方が良いとも述べていますが、まず第一に、再帰はスタックオーバーフローを引き起こします。さらに、再帰自体はあまり効率的ではなく、再帰の各レベルでデータベースの操作が必要になるため、全体的な効果は理想的ではありません。私の現在のアプローチは、すべてのデータを一度に取り出してから、配列に対して再帰的な操作を実行することです。これをさらに改善できれば、ROOT ルート ノードをレコードの各行に追加できます (現時点では、隣接する親ノードも記録される)ので、枝木を探索する際の効率が良くなり、木を更新する際にも非常に便利になるので、より良い方法となるはずです。
2. 再帰的方法を改善します。記事では、事前にソートされたツリー ノードの左右の値を計算するときに、実際にスタックを配列に置き換え、プッシュとポップを行うトラバーサル方法が使用されています。手動で実装されます。このメソッドが再帰アルゴリズムで参照される場合、再帰を実行するときにスタックの代わりに配列を使用すると、再帰の効率も向上します。
3. 同時実行性。同時実行性を考慮する場合、特にツリーを更新する場合、事前にソートされたツリーの広い領域でノード情報を更新する方法では、ロックとトランザクションのメカニズムの使用に特別な注意を払う必要があります。データの一貫性。
4. 複数のルート ノードまたは複数の親ノードの場合、これは明らかに標準のバイナリ ツリーまたはマルチフォーク ツリーではありません。適応するには、事前にソートされたツリー アルゴリズムと再帰的手法を大幅に改善する必要があります。は自由に適用できるため、この場合は再帰の方が適応性が高くなります。これは、再帰的手法がリンク リストの形式であり、ツリーやグラフをリンク リストで表現できるため、当然ながら適応性が高くなります。
5. 直感的です。プログラムを操作せずにデータベースに保存されたデータを直接観察すると、再帰モードで保存されたデータの方が直感的であることがわかりますが、事前にソートされたツリー内のデータは (階層構造の場合) 直接読み取るのが困難です。これはデータ交換において重要です。影響はありますか?
一般に、私は個人的に再帰的手法を使用することを好みますが、幸いなことに、再帰的に大規模な分類レベルに遭遇したことがないため、再帰的手法を使用する方が改善されます。方法。事前にソートされたツリーは、単純なツリーを解決するための効率的な方法であり、慣れてしまえば非常に優れています。特に、葉ノードからルート ノードへの逆探索が非常に便利です。
フウルフ
www.fwolf.com
» このコメントに返信
あなたの返信を見てとてもうれしいです
shuke によって投稿されました。投稿日は 2004 年 3 月 18 日 - 午前 5 時 47 分です。
この記事を注意深く読んでいただけたことをとてもうれしく思います。この記事はもともと sitepoint.com で公開されたもので、これから始めたいと考えている友人にいくつかの方法を紹介したいと考えて翻訳しました。あなたの方法もとても良いので、機会があれば試してみたいと思います。 (興味があれば、上記の例に基づいてチュートリアルとしてメソッドと具体的な実装コードを作成してみてはいかがでしょうか。そうすれば、より実践的な例で誰もが真似できるようになります) データベースへのマルチレベル構造の保存について質問がある場合研究に興味がある方は、参考として使用できる他の 2 つのリンクを紹介します。
ワンタイムクエリと配列ソートスクリプトの一般的な4つの方法を紹介します。あなたのスクリプトはこれよりも優れているはずです。
さらに、drupal には、分散ユーザー認証システムという高度な機能もあります。どの drupal サイトでも登録していれば、ログインして他の Drupal サイトにアクセスできます。なかなか興味深いですね。
幸運をお祈りしています!
» このコメントに返信
ループを使用したツリーの構築が実装されました
2004 年 3 月 25 日 - 午後 10 時 10 分にゲストによって投稿されました。
前回ご提供いただいた情報はすべて読みましたが、最初の記事は正直あまり新しい内容はなく、2 番目の記事は実際には PHP3 で書かれており、プログラムの構造がよくわかりませんでした。詳細は説明されていませんでした。使用されている関数の交差が多すぎます。
たまたま、システム内で階層的なユーザー ロールを使用する必要があったので、配列のアイデアに基づいて走査を書き留めました。整理する時間がなかったので、ここに記載します。データベースは ADODB であり、プログラムは主に PHP の強力な配列演算を使用し、再帰を実行することを明確に説明できれば幸いです。コメントも同様の方法ですが、結果を処理するタイミングが異なります。
<?php
/**
* ショーリスト
* @アクセスパブリック
*/
関数 DispList()
{
// インデントなしの表示モード
// $this->mIsDispListIndex = true;
// echo('<p align="right"><a href="?action=new&part=role">新しいロールを追加する</a> </p>'); ">新しい役割を追加</a> </p>');"
//
// $this->mListTitle = 'ユーザーロールリスト';
// $this->SetDataOption('list');
//
// $this->SetQueryTable( array($this->mTableUserRole) );
//
// //クエリ順序
// $this->SetQueryOrder( 'asc', $this->mTableUserRole, 'sequence' );
//
// $this->Query('list');
//parent::DispList();
// //配列をスタックとして使用する別の表示方法、A: スタックにプッシュするときにロールを保存し、プッシュ後にソースを削除します。
// $this->CheckProperty('mrDb');
// $this->CheckProperty('mrSql');
// $this->mrSql->Select('役割, タイトル, 親');
// $this->mrSql->From($this->mTableUserRole);
// $this->mrSql->Orderby('親, シーケンス');
// $this->mRs = $this->mrDb->Execute($this->mrSql->Sql());
// if (0 < count($this->mRs))
// {
// $source = & $this->mRs->GetArray() // 数値インデックス
// $stack = 配列('');
// $stacki = array(-1); // スタックに対応し、スタック内のデータのレベルをツリーに記録します
// $target = array();
// while (0 < count($stack))
// {
// $item = array_shift($stack);
// $lev = array_shift($stacki);
// if (!empty($item))
// {
// //ここで処理したデータをターゲット配列に入れます
// array_push($target, str_repeat(' ', $lev) . $item);
// //$s1 = str_repeat(' ', $lev) ;
// }
// $del = array() // $source から削除されるノード
// $ar = array() // スタックに追加する必要があるノード
// foreach ($source as $key=>$val)
// {
// //一致する子ノードを検索します
// if (empty($item))
// {
// $find = empty($source[$key]['parent']);
// }
//それ以外
// {
// $find = ($item == $source[$key]['parent']);
// }
// if ($find)
// {
// array_unshift($ar, $source[$key]['role']);
// $del[] = $key;
// }
// }
// foreach ($ar として $val)
// {
//array_unshift($stack, $val);
//array_unshift($stacki, $lev + 1);
// }
// foreach ($del として $val)
// {
// unset($source[$val]);
// }
// echo(implode(', ', $stack) . '<br />' . implode(', ', $stacki) . '<br />' . implode(', ', $target) . '< br /><br />');
// }
//デバッグ_配列();
// }
//それ以外
// {
// echo('<center>データは取得されません</center>');
// }
//配列をスタックとして使用する別の表示方法、B: スタックをプッシュするときに配列インデックスを保存し、スタックからポップアウトし、使用後にソースを削除します。
$this->CheckProperty('mrDb');
$this->CheckProperty('mrSql');
$this->mrSql->Select('役割、タイトル、親');
$this->mrSql->From($this->mTableUserRole);
$this->mrSql->Orderby('親, シーケンス');
$this->mRs = $this->mrDb->Execute($this->mrSql->Sql());
if (!empty($this->mRs) && !$this->mRs->EOF)
{
$source = & $this->mRs->GetArray(); //数値インデックス
$stack = 配列(-1);
$stacki = array(-1); //スタックに対応し、スタック内のデータのレベルをツリーに記録します
$target = 配列();
while (0 < count($stack))
{
$item = array_shift($stack);
$lev = array_shift($stacki);
if (-1 != $item)
{
//ここで処理したデータをターゲット配列に入れます
$s1 = str_repeat(' ', $lev) . '<a href="?action=disp&part=role&role=' . $source[$item]['role'] . '">' . ['タイトル'] '</a>';
$s2 = '<a href="?action=edit&part=role&role=' . $source[$item]['role'] . '">編集</a> <a href="?action=delete&part=role&role= ' . $source[$item]['role'] '">削除</a>';
array_push($target, array($s1, $s2));
}
$del = array(); // $source から削除されるノード
$ar = array(); //スタックに追加する必要があるノード
foreach ($source として $key=>$val)
{
// 一致する子ノードを検索します
if (-1 == $item)
{
$find = empty($source[$key]['parent']);
}
それ以外
{
$find = ($source[$item]['role'] == $source[$key]['parent']);
}
if($find)
{
array_unshift($ar, $key);
}
}
foreach ($ar として $val)
{
array_unshift($stack, $val);
array_unshift($stacki, $lev + 1);
}
//ソースから削除
unset($source[$item]);
//echo(implode(', ', $stack) . '<br />' . implode(', ', $stacki) . '<br />' . implode(', ', $target) . '< br /><br />');
}
//出力
echo('<p align="right"><a href="?action=new&part=role">新しい役割を追加</a> </p>');
array_unshift($target, array('role', 'operation'));
$this->CheckProperty('mrLt');
$this->mrLt->SetData($target);
$this->mrLt->mListTitle = 'ユーザー役割リスト';
$this->mrLt->mIsDispIndex = false;
$this->mrLt->Disp();
}
それ以外
{
echo('<center>データは取得されません</center>');
}
} // 関数 DispList の終了
?>