私は自分がプログラミングのプロだとは思いませんが、時には本当にやりたいと思うこともありますが、それでも、この方法でツリーを構築するのは間違っていると思います。
コメントツリーではなく、メニューツリーを作成します。 メニューを作成する私の方法は、変更やコメントツリーの作成が簡単です。 メニューには、任意の数のサブメニューを含めることができます。 私のメニューテーブル構造は次のとおりです。
m_Id
m_Position
m_LineId
m_ParentId
m_Type
m_Title
m_Description
m_Data
木を建てることに戸惑い、自分で考えるのが面倒だったので、これらのタイネットの既製のソリューションを探すことにしました。 既製のソリューションのようなものですが、これらの既製のソリューションは、私に合わないフレームワークで実装されました。残りは、データベースクエリの束でツリーが構築されました。 、そして、あらゆる種類のCOUNT()およびその他のがらくたを伴う倒錯なしに。 時間を無駄にせず、メニューツリーを構築するクラスのコードを提供します。
class MenuFactory extends BaseClass { /** * * var mixed */ public $MenuTree; /** * * @var mixed , .. , */ public $MenuList; private $level=0; /** * * @param int Id * @param int/bool bool==true - , . , * @return mixed */ public function GetMenu($menu_id, $return_as_list = false) { // $this->sql->Query("SELECT * FROM `menus` WHERE `m_LineId`=?d ORDER BY m_Position, m_ParentId", $menu_id); // $this->MenuList = array(); $ml = array(); while($r = $this->sql->Assoc()) { // MenuItem $m = CommonUtils::ObjectFromArray('MenuItem', CommonUtils::DelPrefix($r,'m_')); // $this->MenuList[] = $m; // , $ml[] = clone $m; } // $return_as_list == true if(is_bool($return_as_list) && $return_as_list) { return $this->MenuList; } // , $return_as_list == false else if(!$return_as_list) { $this->MenuTree = array(); $this->MenuTree = $this->GetMenuChilds(0,$ml); return $this->MenuTree; } // , $return_as_list == , , else if(is_numeric($return_as_list)) { $this->MenuTree = array(); $this->MenuTree = $this->GetMenuChilds(0,$ml, $return_as_list); return $this->MenuTree; } //print_r($this->menuTree); } /** * * @param int $p_id Id * @param mixed $menuList , * @param int $levels * @return mixed */ private function GetMenuChilds($p_id, $menuList, $levels = null) { // , $a = array(); // foreach($menuList as $item) { //TODO: Optimize code // ParentId id, // , . if($item->ParentId == $p_id) { $this->level++; // $levels , $this->levels, // , $levels if($levels != null && $this->level <= $levels) { // . // $this->MenuList , ParentId id , // , $item->ChildMenus = $this->GetMenuChilds($item->Id, $menuList, $levels); // $this->level $item->Level = $this->level; // $a[] = $item; } else { // $this->MenuList $item->ChildMenus = $this->GetMenuChilds($item->Id, $menuList); $item->Level = $this->level; } $this->level--; // $levels , ParentId , // , if($levels == null) { $a[] = $item; } } } // return $a; } /** * * @return mixed */ public function GetMenuList() { return $this->MenuList; } /** * * @param int $menu_id Id , * @return mixed */ public function GetMenuPathTo($menu_id) { // , // , . $a = array(); for($i=0; $i<count($this->MenuList); $i++) { // id id if($this->MenuList[$i]->Id == $menu_id) { // $a[] = $this->MenuList[$i]; // , , // $menu_id , id $menu_id = $this->MenuList[$i]->ParentId; // , ) $i=-1; } } // -> , // , : -> return array_reverse($a); } /** * * @param int $menu_id Id , * @return MenuItem */ public function GetMenuById($menu_id) { $this->sql->Query("SELECT * FROM `menus` WHERE `m_Id`=?d LIMIT 1", $menu_id); $record = $this->sql->Assoc(); if($record) { $record = CommonUtils::DelPrefix($record,'m_'); return CommonUtils::ObjectFromArray('MenuItem', $record); } return null; } }
メニュー項目を表すクラスのコード:
class MenuItem { public $Id; public $Position; public $ParentId; public $LineId; public $Type; public $Title; public $Description; public $Data; public $Level; public $ChildMenus; }
PHPコードを強調表示する方法はわかりませんが、それについては知りません。
原則として、 GetMenu()メソッドを使用すると、メニューツリーとメニューの両方をリストとして取得できることは明らかです。 さらに、2番目の引数として0から無限大までの数値を指定すると、メニューツリーはこの数値に等しい深さでロードされます。
GetMenuPathTo()メソッドは 、IDがパラメーターとして渡されるメニュー項目へのパスを探します。このメソッドは、サイト上のパンくずリストを整理するために実装されました
CommonUtils :: DelPrefix()を使用すると、連想配列のプレフィックスを削除して、メニュー項目のプロパティの実際の名前を取得できます。
CommonUtils :: ObjectFromArray()は、それに割り当てられたクラスのオブジェクトを返します。このオブジェクトには、2番目のパラメーターで渡された連想配列の値が設定されます。
誰かがこのコードを気に入らないかもしれないとは言いませんが、データベースへの1回のクエリで、メニューツリーを構築するのに非常に役立ちます。
すべて成功。
upd :// kamentyを「木を構築するために%% methodname%が機能しなかった理由」または「なぜmethodname%を使用しなかったのですか?」というスタイルで去るすべての人に私は厳declareに宣言します。 実装をもたらしました。 おそらくあなたのmethodname%を知らなかったでしょう。 いずれにせよ、あなたのコメントは私にとって重要であり、十分な注意なしに残されません。