Bir ağaç görünümü Bina

2 Cevap php

Ben bu sorun üzerinde biraz odunum ve ben bir süre için şimdi bunu düşünüyordum. Ben bir görevleri tutan benim DB bir tablo var. Her görev parent_id alanında bu birincil anahtarı tutarak bir üst görev olabilir. Ben bu görevleri bağlantılı olabilir nasıl derin limit yok.

+-----------+-------+-----+
| Field     | Type  | Key |
+-----------+-------+-----+
| id        | int   | PRI |
| parent_id | int   | MUL |
+-------------------+-----+

Bir parent_id olmayan bir görev bir "proje" olduğunu ve tüm görevleri bir ebeveyn görevi paylaşarak görev grupta toplanabilir. Şimdi projenin tüm torunu ile bir HTML seçme kutusunu doldurmak istiyorum.

Task 1
  -Task 1.1
  -Task 1.2
    -Task 1.2.1
    -Task 1.2.2
  -Task 1.3
Task 2

Bundan nasıl gidebilir? Ben özyinelemeli fonksiyon çeşit sırayla olduğunu anlamaya ama ben gerçekten bu konuda gitmek nasıl anlamaya gibi olamaz.

Herhangi bir yardım büyük apprecaited olacaktır. :)

2 Cevap

Ben çok storing hierarchical data in a database hakkında bu makaleyi okumanızı öneririz. Orada tartışılan iki algoritma vardır ve ihtiyaçlarına bağlı olarak, ikisinden biri uygun olabilir.

Adjacency List Model

Bu şu anda ne var. Ağacın her düğümü ebeveyn var bir başvuru saklar, ve ardışık bir ağacın her düzeyde seçme ve düğümleri yineleme tarafından bir düğüme yolunu belirleyebilirsiniz. Bu uygulamak için basit, ama dezavantajı bir düğüme belirli bir yol belirlemek için, özyinelemeli sorgular gerekli olmasıdır. Ağacınızı değişiklikler (yani yazıyor) bir çok konu ise, bu dinamik olarak her düğümü bulma sürekli değişen ağaç ile iyi çalışır, gitmek için iyi bir yoldur. Salt ağır oluyor ise, özyineleme bazı yükü var.

Modified Preorder Tree Traversal

Benim en sevdiğim, çok düzgün bir algoritma var. Bunun yerine (eğer kolaylık sağlamak amacıyla yine yapabilir) üst başvuru depolanması, size "sol" ve verilen her düğüm için "doğru" düğümler bir referans olarak saklamak. Bir düğüme tüm yolu, tek bir seçme sorgusu tespit, veya tersine, bir düğümün tüm çocuklar. Algoritması uygulamak zordur, ama okuma-ağır ağaçlar için performans faydaları vardır. Dezavantajı bir düğüm taşınır veya eklenen her zaman, ağacın tüm dalları yeniden hesaplanması gerekir, bu yüzden yazma ağır veri setleri için uygun olmayabilir olmasıdır.

Her neyse, bu yazı size bazı fikirler verir umuyoruz. Bu iyi biri.

Bu, özyinelemeli bir HTML formu kurmak için veritabanı geçiş nasıl bir örnektir. Bu zombat bir "komşuluk listesi Modeli" olarak ifade eder ne bir uygulamasıdır.

Bu iki işlevleri kullanır: biri sadece "üst düzey" unsurları (proje) almak için; ve bir özyinelemeli, belirli bir öğenin tüm çocukları almak için. Ben daha sonra bir HTML formu doldurmak için kullanabilirsiniz.

<?php
/**
 * Fetches all the projects and returns them as an array.
 * "Projects" meaning: tasks without a parent.
 * @return array
 */
function getProjects() {
    $sql = "SELECT id FROM tree WHERE parentID IS NULL";
    $result = mysql_query($sql) or die(mysql_error());
    $results = array();
    while($row = mysql_fetch_assoc($result)) {
        $results[] = $row['id'];
    }
    return $results;
}

/**
 * Fetches all tasks belonging to a specific parent.
 * Adds HTML space entities to represent the depth of each item in the tree.
 * @param int $parent_id The ID of the parent.
 * @param array $data An array containing the dat, filled in by the function.
 * @param int $current_depth Indicates the current depth of the recursion.
 * @return void
 */
function getTasks($parent_id, &$data, $current_depth=1) {
    $sql = "SELECT id FROM tree WHERE parentID = {$parent_id}";
    $result = mysql_query($sql) or die(mysql_error());
    while($row = mysql_fetch_assoc($result)) {
        $data[] = str_repeat('&nbsp;', $current_depth) . '- ' . $row['id'];
        getTasks($row['id'], $data, $current_depth + 1);
    }
}


/*
 * Fetch all the data and set it up so it can be used in the HTML
 */
mysql_connect('localhost', 'usr', 'pwd');
mysql_select_db('test');

// Get all the projects, adding a "-" as the initial value of the box.
$projects = array_merge(array('-'), getProjects());

// Fetch the tasks.
// If no project has been selected, just show a "please select"
$tasks = array();
if(isset($_GET['project']) && $_GET['project'] != '-') {
    getTasks($_GET['project'], $tasks);
}
else {
    $tasks = array('Select a project');
}

mysql_close();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <title>Tree Select Example</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
        <select name="project" onchange="this.parentNode.submit();">
            <?php
            foreach($projects as $_project) {
                $selected = ($_project == @$_GET['project']) ? ' selected' : '';
                echo "<option value=\"{$_project}\"{$selected}>{$_project}</option>";
            }
            ?>
        </select><br>
        <select name="tasks[]" multiple size="10">
            <?php
            foreach($tasks as $_task) {
                echo "<option value=\"{$_task}\">{$_task}</option>";
            }
            ?>
        </select><br>
        <input type="submit">
    </form>
    <pre><?php print_r($_GET); ?></pre>
</body>
</html>