0

私は次のようなDBを持っています:

id  text           parent
1   Parent 1        0   
2   Child of 1      1   
3   Sibling         1   
4   Another Parent  0 
5   A first child   4

そのため、親をリストするツリー構造をキャプチャしようとしています。私は他のオプション (入れ子になったセットだと思いますか?) を認識していますが、今のところこれに固執するつもりです。私は今、DB からデータを取得して、PHP のネストされた配列構造に入れようとしています。私はこのような機能を持っています:

class Data_Manager
{   
    public $connection = '';
    public $collection = array();

    function __construct() {
        $this->connection = mysql_connect('localhost', 'root', 'root');
        $thisTable = mysql_select_db('data');
            // error handling truncated
    }


    function get_all() {
        $arr = &$this->collection;

        $this->recurseTree('', 0, $arr);
        var_dump($arr);
    }

    function recurseTree($parent, $level, $arrayNode) {
        $result = mysql_query('SELECT * FROM tasks WHERE parent="' . $parent . '";');

        while ($row = mysql_fetch_array($result)) {
            $row['children'] = array(); //where I'd like to put the kids    
            $arrayNode[$row['id']]= $row;
            $this->recurseTree($row['id'], $level+1, $arrayNode[$row['id']]);
        }
    }
}

だから、連想配列のネストされたツリーのようなものを作りたいと思っていますが、それを行う方法がわかりません。渡した配列に何も書き込まれていないようで、再帰で自分自身を見失っています。次のような結果になるこの最後のこぶを乗り越えるのを手伝ってくれる人はいますか?

[
Parent1 => [
               children => ['Child of 1', 'Sibling']
           ],
AnotherParent => [
                     children => ['First Child']
                 ]
]

また、出力の特定の形式にはあまり関心がありません。これは JSON に変換されますが、クライアント側のハンドラーの作成についてはまだ扱っていないため、正確な構造については心配する必要はありません。

ありがとう!

4

4 に答える 4

5

これを試して。

$sql = "SELECT * FROM tasks";
$r = mysql_query($sql, $conn);
$arr = array();
while ($row = mysql_fetch_assoc($r))
   $arr[] = $row

function build($arrayIn, $parent)
{
    $makeFilter = function($p) {return function($x) use ($p) {return $x['parent'] == $p;};};
    $f = $makeFilter($parent);
    $these = array_filter($arrayIn, $f);
    $remaining = array_diff_assoc($arrayIn, $these);
    $ans = array();

    foreach($these as $cur)
    {
       $ans[$cur['text']] = build($remaining, $cur['id']);
    }
    return $ans ? $ans : null;
}

$tree = build($arr, 0)
echo_r($arr);
echo "becomes<br />";
echo_r($tree);

ここに私の出力があります:

Array
(
[0] => Array
    (
        [text] => a
        [id] => 1
        [parent] => 0
    )

[1] => Array
    (
        [text] => b
        [id] => 2
        [parent] => 0
    )

[2] => Array
    (
        [text] => c
        [id] => 3
        [parent] => 1
    )

[3] => Array
    (
        [text] => d
        [id] => 4
        [parent] => 2
    )

[4] => Array
    (
        [text] => e
        [id] => 5
        [parent] => 2
    )

[5] => Array
    (
        [text] => f
        [id] => 6
        [parent] => 3
    )

)

becomes

Array
(
[a] => Array
    (
        [c] => Array
            (
                [f] => 
            )

    )

[b] => Array
    (
        [d] => 
        [e] => 
    )

)
于 2010-11-22T14:20:42.247 に答える
0

ここでは、再帰関数は本当に必要ありません。1 つのデータベース クエリを使用してすべてのデータを取得し、それをループします。複数のデータベース呼び出しよりもはるかに高速です。

データを MySQL に保存していると仮定して、階層内のすべてを返す隣接リスト テーブルに対して SELECT ステートメントを記述する方法については、この質問への回答を参照してください。つまり、MySQL セッション変数を使用します。次に、結果セットを取得してループし、スタックを使用して最後の親 ID をプッシュ - ポップ - ピークして、データ構造のインデントを決定します。

于 2010-11-22T15:21:03.393 に答える
0

この疑似コードが役に立ちます。

関数 getTasks($parent = 0){
    $タスク = 配列();
    $query = mysql_query("select * from table where parent = $parent");
    $行 = 配列();
    while(($row = mysql_fetch_assoc($query)) !== FALSE){ $rows[] = $row; }
    if(count($rows)){
        $tasks[$parent][] = getTasks($parent);
    } そうしないと {
        $tasks を返します。
    }
}

$tasks = getTasks();
于 2010-11-22T04:35:07.707 に答える
0

これは、あらゆる種類の隣接リスト タスクを処理するために作成した PHP クラスです。

http://www.pdvictor.com/?sv=&category=just+code&title=adjacency+model

于 2012-12-03T04:16:56.783 に答える