1

問題:特定の状況に対して再帰関数を作成する方法が思いつきません。

状況:

Mysql DB
id | root | name |
ウィッチ カテゴリを示す場所rootは、サブカテゴリです。

HTML の外観:

    <li><a href="#"><p class="Tier0">Datori</p></a>
                    <ul style="display: block">
                         <li><a href="#"><p class="Tier1">Cookies</p></a></li>
                         <li><a href="#"><p class="Tier1">Events</p></a></li>
                         <li><a href="#"><p class="Tier1">Forms</p></a></li>
                         <li><a href="#"><p class="Tier1">Games</p></a></li>
                         <li><a href="#"><p class="Tier1">Images</p></a>
                            <ul>
                                <li><a href="#"><p class="Tier2">CSS</p></a></li>
                                <li><a href="#"><p class="Tier2">JavaScript</p></a></li>
                                <li><a href="#"><p class="Tier2">JQuery</p></a></li>
                            </ul>
                         </li>
                         <li><a href="#"><p class="Tier1">Navigations</p></a>
                            <ul>
                                <li><a href="#"><p class="Tier2">CSS</p></a></li>
                                <li><a href="#"><p class="Tier2">JavaScript</p></a></li>
                                <li><a href="#"><p class="Tier2">JQuery</p></a></li>
                            </ul>
                        </li>
                         <li><a href="#"><p class="Tier1">Tabs</p></a></li>
                    </ul>
                </li>
                <li><a href="#"><p class="Tier0">Washing Machines</p></a>

すべてを出力するには、どのような PHP 関数が必要ですか?

4

1 に答える 1

10

どうですか:

function recurse($categories, $parent = null, $level = 0)
{
    $ret = '<ul>';
    foreach($categories as $index => $category)
    {
        if($category['root'] == $parent)
        {
            $ret .= '<li><a href="#"><p class="Tier' . $level . '">' . $category['name'] . '</p></a>';
            $ret .= $this->recurse($categories, $category['id'], $level+1);
            $ret .= '</li>';
        }
    }
    return $ret . '</ul>';
}

この関数では、最初に使用可能なカテゴリのリスト全体についてデータベースにクエリを実行する必要があり、ルート カテゴリの値が null であることを前提としていますが、現在のスキーマの動作に応じて -1 または 0 を受け入れるように関数を変更できます。

$categories = { get from database into an multi-dimensional array };
$Tree = $this->recurse($categories);
echo $Tree;

親の子が存在しない場合に空の UL が表示されないようにするには、次のことを検討してください。

function recurse($categories, $parent = null, $level = 0)
{
    $ret = '<ul>';
    foreach($categories as $index => $category)
    {
        if($category['root'] == $parent)
        {
            $ret .= '<li><a href="#"><p class="Tier' . $level . '">' . $category['name'] . '</p></a>';
            $sub = $this->recurse($categories, $category['id'], $level+1);
            if($sub != '<ul></ul>')
                $ret .= $sub;
            $ret .= '</li>';
        }
    }
    return $ret . '</ul>';
}

ただし、最良の解決策は、データを選択して、各カテゴリに含まれる子カテゴリの数を含む列を含めることです。

select Category.*, (select count(distinct c1.id) from Category as c1 where c1.root = Category.id) as ChildCount from Category

あなたの機能は次のとおりです。

function recurse($categories, $parent = null, $level = 0)
{
    $ret = '<ul>';
    foreach($categories as $index => $category)
    {
        if($category['root'] == $parent)
        {
            $ret .= '<li><a href="#"><p class="Tier' . $level . '">' . $category['name'] . '</p></a>';
            if($category['ChildCount'] > 0)
                $ret .= $this->recurse($categories, $category['id'], $level+1);
            $ret .= '</li>';
        }
    }
    return $ret . '</ul>';
}

それが役立つことを願っていますか?

于 2012-05-28T10:19:28.077 に答える