شنبه ۱ دی ۱۴۰۳ |  عضویت / ورود

بهترین الگوریتم برای شاخه بندی (موضوع بندی) کردن و نمایش آن‌ها به صورت زیرمجموعه‌ای در طراحی وب


Sunday, 2011 December 25   نویسنده: Hamid   تعداد بازدید: 6247 بار  #آموزش PHP‏   امتیاز متوسط: امتیازی داده نشده است

یکی از مباحثی که تقریباً در طراحی هر نوع سیستمی درگیر آن خواهید شد، بحث شاخه‌بندی یا موضوع‌بندی موجودیت‌هاست.

مثلاً: موضوعات مقالات در یک سیستم مدیریت مقالات. شاخه‌ها در سیستم مدیریت موسیقی. شاخه‌بندی در سیستمی مثل تستا به صورتی که هر آزمون زیرمجموعه یک شاخه باشد.

در اکثر مواقع نیاز دارید که یک شاخه بتواند چندین سطح فرزند داشته باشد. به قوی علاوه بر فرزند، نوه و نتیجه هم داشته باشد (شاخه بندی چند سطحی)

به طور مثال به تصویر زیر دقت کنید:

http://tutorials.aftab.cc/web_designing/php/categorize/categorizing1.png

گروه «شبکه» علاوه بر اینکه خودش فرزند «گروه اصلی» است، فرزندانی به نام‌های «تست» و «TCP/IP» دارد و یک نوه نیز به نام «آی.پی» دارد.

الگوریتم کلی شاخه بندی:

الگوریتم کلی این است که شما در دیتابیس، در جدولی که موضوعات را نگه می‌دارید، یک id به هر موضوع نسبت می‌دهید و علاوه بر آن، یک ستون هم در نظر می‌گیرید برای اینکه آی.دی پدر این موضوع را نگه دارید.

به طور مثال جدول مربوط به تصویر بالا به این صورت است:

http://tutorials.aftab.cc/web_designing/php/categorize/categorizing2.png

مثلاً می‌بینید که والد فتوشاپ برابر با 1 است. یعنی زیرمجموعه گروه اصلی است.

نکته: والد (parent) مربوط به «گروه اصلی» همیشه باید 0 باشد و خودش همیشه باید id اش برابر با 1 باشد. (شما همیشه یک شاخه اصلی دارید با این ویژگی‌ها)
پس اگر بخشی برای ویرایش شاخه‌ها دارید، باید دقت کنید که هیچ وقت کد و والد مربوط به شاخه اصلی نباید قابل تغییر باشد:

برای شاخه اصلی داریم:

http://tutorials.aftab.cc/web_designing/php/categorize/categorizing3.png

(بررسی شده است که چون gid برابر با 1 است، پس این شاخه، شاخه اصلی است و نباید بتواند زیرمجموعه دیگری قرار بگیرد)

 

اما برای موضوعات دیگر داریم:

http://tutorials.aftab.cc/web_designing/php/categorize/categorizing4.png

 

 

 

چگونه شاخه‌ها را به صورت زیرمجموعه‌ای نمایش دهیم؟

یک الگوریتم نیز نیار داریم برای اینکه بفهمیم هر شاخه چه فرزندانی دارد و هر فرزند، خود چه فرزندانی دارد.

این شاید یکی از پیچیده‌ترین الگوریتم‌ها به نظر برسد، اما در کل، با استفاده از یک آرایه و یک تابع بازگشتی می‌توانید این مشکل را رفع کنید:

<?php
function list_groups($parent)
{
    $has_childs = false;
    global $menu_array;

    foreach($menu_array as $key => $value)
    {
            if ($value['parent'] == $parent) 
            {               

                    if ($has_childs === false)
                    {
                            $has_childs = true;
                            echo '<ul style="list-style-image:url(\'images/L.gif\')">';   //چاپ عکس نماد زیرمجموعه (ال شکل) در کنار نام مجموعه

                    }
                    echo '<li>'.$value['id'].'-'.$value['name'].'</a>';
                    list_groups($key);
                    echo '</li>';

            }
    }
    if ($has_childs === true) echo '</ul>';
}
?>

تنها کاری که باید کنید این است که آرایه ‎$menu_array را به این صورت پر کنید:

این آرایه global تعریف شده تا از خارج از تابع قابل پر کردن باشد.

 


$groups_res = mysql_query("SELECT * FROM groups ORDER BY weight");
        
while($groups = mysql_fetch_array($groups_res))
{
    $ts = "";

    $menu_array[$groups['id']] = array('id' => $groups['id'],'name' => $groups['title'],'parent' => $groups['parent'],'tests'=>$ts);
}
?>

 

دقت کنید:

من لیست موضوعات را از دیتابیس خوانده‌ام و در groups ریخته‌ام.

- یک خانه با اندیس id داریم که آی.دی هر گروه در آن قرار می‌گیرد.

- یک خانه با اندیس name داریم که عنوان گروه در آن است.

- یک خانه با اندیس parent داریم که والد هر شاخه در آن ریخته شده است.

- یک خانه به نام tests در نظر گرفته‌ام که شاید برای کار شما چندان ضرورت نداشته باشد، اما به هر حال، آن خانه شامل لیست آزمون‌هایی است که زیرمجموعه این گروه خاص هستند. (من نحوه پر شدن ‎ ‎$ts با آزمون‌ها را از حلقه حذف کرده‌ام. فقط به این دلیل گذاشتم که بدانید می‌توانید یک آرایه را به عنوان یکی از عناصر آرایه menu_array در نظر بگیرید. خیلی از اوقات لازم است)

 

در نهایت، هر وقت خواستید لیست موضوعات نشان داده شود، تابع list_groups را به این صورت فراخوانی کنید:

list_groups(0);

این کد یعنی فرزندان شاخه 0 را لیست کن. همانطور که می‌دانید، 0 یعنی همان شاخه اصلی.

 

 

توجه:

خیلی از اوقات شما یک فیلد به نام «وزن» یا weight نیاز دارید که بالاتر بودن یا پایین‌تر بودن یک آزمون در لیست‌ها را با آن تعیین کنید. مثل من می‌توانید یک دکمه جلو هر شاخه بگذارید که با کلیک روی آن یک واحد بر وزن آزمون افزوده شود و یا یکی کم شود:

http://tutorials.aftab.cc/web_designing/php/categorize/categorizing5.png

فقط موقع لیست کردن، همانطور که در کد بالا می‌بینید، باید بر اساس weight بچینید: ORDER BY weight

موفق باشید؛
حمید رضا نیرومند

 

آدرس کوتاه مقاله:

http://yourl.ir/categorize

کلمات کلیدی:

categorize, cat,folder,subject, شاخه , پوشه بندی , موضوع بندی

 


.



ارسال سؤال یا نظر


1- ehsan:
بوسیله: , در: Saturday, 2014 February 22-کد: 9605
ایول بعد یه هفته تلاش نتونستم ولی خیلی حال دادی مرسی


2- محمدعلی:
بوسیله: , در: Monday, 2018 January 22-کد: 15507
اقا خیلی خیلی عالی بودrnدمت گرم مشتی

Tutorials ©