PDA

View Full Version : آموزش: منو های درختی با بی نهایت سطح



djsaeedkhan
دوشنبه 19 دی 1390, 19:27 عصر
با سلام خدمت دوستان
مدتی بود دنبال این بودم که چگونه یه منوی درختی با بینهایت ریشه بسازم
بعد از جستجو های فراوان راحت ترین راه ممکن رو پیدا کردم
و گذاشتم تا بقیه دوستان نیز استفاده کنن

مرحله اول
یه آرایه باید بسازید به این شکل (می تونید با یه حلقه از دیتابیس بخونید و آرایه رو پر کنید)

$menu = Array( // Presumed to have been coming from a SQL SELECT, .
Array('id'=>1,'title'=>'Menu 1', 'parent_id'=>null),
Array('id'=>2,'title'=>'Sub 1.1', 'parent_id'=>1),
Array('id'=>3,'title'=>'Sub 1.2', 'parent_id'=>1),
Array('id'=>4,'title'=>'Sub 1.3', 'parent_id'=>1),
Array('id'=>5,'title'=>'Menu 2', 'parent_id'=>null),
Array('id'=>6,'title'=>'Sub 2.1', 'parent_id'=>5),
Array('id'=>7,'title'=>'Sub Sub 2.1.1', 'parent_id'=>6),
Array('id'=>8,'title'=>'Sub 2.2', 'parent_id'=>7),
Array('id'=>9,'title'=>'Menu 3', 'parent_id'=>null),
);


مرحله دوم
متغیر منو رو به این تابع پاس کنید تا چاپ بشن

function has_children($rows,$id) {
foreach ($rows as $row) {
if ($row['parent_id'] == $id)
return true;
}
return false;
}
function build_menu($rows,$parent=0)
{
$result = "<ul>";
foreach ($rows as $row)
{
if ($row['parent_id'] == $parent){
$result.= "<li>{$row['title']}";
if (has_children($rows,$row['id']))
$result.= build_menu($rows,$row['id']);
$result.= "</li>";
}
}
$result.= "</ul>";

return $result;
}
echo build_menu($menu);



اگر سوال یا مشکلی بود بفرمایید
با تشکر از کلید تشکر

ss3701
دوشنبه 19 دی 1390, 23:43 عصر
سلام
اگه ممکنه فایل php هم بزار

رضا قربانی
پنج شنبه 31 فروردین 1391, 02:27 صبح
آقا من نتونستم اینو با Sql ردیف کنم . اگه امکانش هست زحمتش رو بکشیید و از بانک بخونیدش و منو رو درست کنید . ممنون می شم.

djsaeedkhan
پنج شنبه 31 فروردین 1391, 13:32 عصر
آقا من نتونستم اینو با Sql ردیف کنم . اگه امکانش هست زحمتش رو بکشیید و از بانک بخونیدش و منو رو درست کنید . ممنون می شم.

سلام
شما باید یه فرم درست کنی که بگه کی زیر مجموعه کی هست.
ریشه های شما همون (فکر کنم) استان ها میشه.
هر استان یه آیدی داره و یه پرنت آیدی. برای استان پرنت آیدی نال میذاری
بعد میرسه به استان ها. میگی پرنت آیدی هر شهر آیدی استان هست. یعنی پدر هر شهر آیدی استان هست.
مثلا اصفهان آیدی 1--> پرنت آیدی نال و کاشان آیدی 2--> پرنت آیدی 1
همه اینا رو که ذخیره کردید به فرمت بالا از دیتابیس می خونید و یه آرایه میسازی و بعد میدی به تابع تا برات نمایش بده.

نشد خبر بده

رضا قربانی
پنج شنبه 31 فروردین 1391, 17:02 عصر
من یک آی دی دارم. اصلا به قضیه من کاری نداشته باشید. اینو از طریق بانک پیاده سازی کنید من ببینم خودم راهم رو پیدا می کنم.

ممنون می شم.

djsaeedkhan
جمعه 01 اردیبهشت 1391, 00:09 صبح
public function CreateTreeMenu() {include_once("model/dbconnect.php");
$DbConnect=new DbConnect();
$sql="select * from category";
$result=mysql_query($sql);
$arr="Array(";
while($row=mysql_fetch_assoc($result))
{$arr.="Array('id'=>'".$row["cat_id"]."' ,'title'=>'".$row["cat_name"]."', 'parent_id'=>'".$row["cat_parent"]."'),";}
$arr.=");";
eval("\$str = $arr;");
function has_children($rows,$id) {
foreach ($rows as $row) {
if ($row['parent_id'] == $id)
return true;
}
return false;
}
function build_menu($rows,$parent=0)
{ $result = "<ul id=li_cat>";
foreach ($rows as $row)
{
if ($row['parent_id'] == $parent){
$result.= "<li ><a href=".siteinfo("SiteDir")."info/cat_lesson?id={$row['id']}>{$row['title']}</a>";
if (has_children($rows,$row['id'])){
$result.= build_menu($rows,$row['id']);
}
$result.= "</li>";
}
}
$result.= "</ul>";
return $result;}
return build_menu($str);}

armsoftpc
جمعه 01 اردیبهشت 1391, 12:57 عصر
به نام خدا
با سلام
واقعا چیز مفیدی بود، اما شما اطلاعات را به صورت string نمایش می دهید ، در صورتی که ما بخواهیم ، اطلاعات به صورت array دریافت شوند ، چه بکنیم! منظور آرایه های تو در تو نیست ، بلکه مثلا یک پدر با parrent_id=0 انتخاب شود ، سپس تمامی فرزندانش زیر آن قرار گیرند ، ( یعنی فرزند بعدی اش(مثلا علی) با شما آی دی 2 و اگر این فرزند دیگری داشت(مثلا حسن) آی دی 3 به آن دهد و اگر نداشت هم سطح بعدی علی با آی دی 3 گذاشته شود و ... و سپس به سراغ پدر بعدی (سطری با parrent_id=0 برود) و همین طور این کار ادامه یابد.
فکر کنم منظورم را متوجه شدید.
موفق باشید.

djsaeedkhan
جمعه 01 اردیبهشت 1391, 23:23 عصر
به نام خدا
با سلام
واقعا چیز مفیدی بود، اما شما اطلاعات را به صورت string نمایش می دهید ، در صورتی که ما بخواهیم ، اطلاعات به صورت array دریافت شوند ، چه بکنیم! منظور آرایه های تو در تو نیست ، بلکه مثلا یک پدر با parrent_id=0 انتخاب شود ، سپس تمامی فرزندانش زیر آن قرار گیرند ، ( یعنی فرزند بعدی اش(مثلا علی) با شما آی دی 2 و اگر این فرزند دیگری داشت(مثلا حسن) آی دی 3 به آن دهد و اگر نداشت هم سطح بعدی علی با آی دی 3 گذاشته شود و ... و سپس به سراغ پدر بعدی (سطری با parrent_id=0 برود) و همین طور این کار ادامه یابد.
فکر کنم منظورم را متوجه شدید.
موفق باشید.



سلام
اینی که شما فرمودید رو من دیدم ولی تا حالا رو همچین چیزی فکر نکردم
باید روش کار کرد
ولی شاید بشه تا merg و pop_array (اسماشو مطمئن نیستم) بشه به نتیجه رسید
البته یه کارم میشه کرد. شما به فرمت رشته که در آوردی بعد یا با عبارت های با قاعده یا explode اونو به آرایه تبدیل کن

با سپاس

armsoftpc
دوشنبه 04 اردیبهشت 1391, 23:35 عصر
به نام خدا
با سلام

البته یه کارم میشه کرد. شما به فرمت رشته که در آوردی بعد یا با عبارت های با قاعده یا explode اونو به آرایه تبدیل کن
سرعت رو حسابی پایین میاره ، خودم روش یه سری کار کرده بودم.

اینی که شما فرمودید رو من دیدم ولی تا حالا رو همچین چیزی فکر نکردم
باید روش کار کرد
ولی شاید بشه تا merg و pop_array (اسماشو مطمئن نیستم) بشه به نتیجه رسید
این روش ها جواب نمی ده، من میدونم باید چه اتفاقی بیفته ، اما وقتی می خوام کدش رو بنویسم شدیدا گیج میشم، واقعا کدی پیچیده ای دارد (با این تعداد خط های آن محدود است) ، پیچیدگی آن هم به این دلیل است که خود تابع رو داخل خودش فراخوانی می کنیم که واقعا درکش (برای آرایه کردن این کار) سخته، خیلی هم سخته!
من یه کد خارجی که دقیقا کاری که گفتم را انجام میدهد ، دارم و تعداد خط های آن کم است و حدودا 2 هفته طول کشید که کد هاش رو کوتاه کردم ، اما متاسفانه این کد ها سرعت وقتی که فراخوانی می شوند ، بدلیل پیچیدگی و چندبار فراخوانی آن و شی گرایی بودن کد سرعت را حسابی پایین می آورد، نمی دونم چگونه سرعت را در این مورد بالا ببرم ، چون آرایه در کلاس ساخته می شود و فرزند ها حتما باید زیر پدرشان قرار گیرند(در آرایه) نمی توان از limit در کدهای sql و محدودیت در php استفاده کرد.
من کد را برای شما می گذارم، (خیلی حقیقتا قبلا برای این کد وقت گذاشتم ) شما هم از آن استفاده کنید ، اگر هم تمایل داشتید ، نحوه ی بالا بردن سرعت هم بگویید.

$src=array();

$myvalue="";


class tree_cat {

public $m_postid;
public $m_title;
public $childlist;
public $m_depth;



public function tree_cat($postid=0, $title='', $children=1, $depth=-1)
{
$this->m_postid = $postid;
$this->m_title = $title;
$this->childlist = array();
$this->m_depth = $depth;

$children=$this->has_children($postid);

global $myvalue;

if($children)
{
$result=arm_query("select * from `cats` where `parent_id` = '$postid' order by `cat_id`", 1, "درخواست را نمی تواند اجرا کند", 0);

for ($i=0; $row = @$result->fetch_assoc(); $i++)
{
$this->childlist[$i]= new tree_cat($row['cat_id'], $row['cat_name'], $children, $depth+1);

}
$myvalue=$this->childlist;
}

}


public function has_children($id)
{
$children=arm_query("select `parent_id` from `cats` where `parent_id` = '$id'");
$children=$children->num_rows;
if($children>0)
$children=1;
else
$children=0;

return $children;
}



public function display($row, $t_show="title")
{
global $src, $myvalue;

$sp=$this->arm_nbsp($this->m_depth);


if($t_show=="title")
$src[$row] = $sp.$this->m_title;
else
$src[$row] = $this->m_postid;

$row++;

$num_children = sizeof($this->childlist);

for($i = 0; $i<$num_children; $i++)
$row = $this->childlist[$i]->display($row, $t_show);


return $row;
}


/* Spacor */
public function arm_nbsp($depth)
{
$space="";
for($i = 0; $i<$depth; $i++)
$space.="&nbsp;&nbsp;&nbsp;";

return $space;
}



/* Send array */
public function send_data()
{
global $src;
array_shift($src);
return $src;
}



public function debugger()
{
global $src, $myvalue;

arm_pr( $myvalue);
}

};






function arm_display_select($t_show, $row = 0 )
{
$tree = new tree_cat;
$tree->display($row, $t_show);
$data=$tree->send_data();

return $data;
}

$cat_ids=arm_display_select("id");
$cat_titles=arm_display_select("title");

دز پناه خدا موفق باشید.