PHP SPL для управления рекурсивным меню - PullRequest
2 голосов
/ 08 мая 2009

У меня есть таблица в базе данных, которая имеет данные категории:

id   title       parent 
1    category 1  0
2    category 2  2
3    category 3  3
4    category 4  0

У каждого родителя может быть идентификатор родительской строки.

Например, категория 3 является дочерним элементом категории 2, который является дочерним элементом категории 1.

category 1
   category 2
      category 3

category 4

1 - Есть ли лучший способ манипулировать этой техникой? 2. Моя реализация состоит в том, чтобы извлечь все строки в одном запросе SQL, затем использовать рекурсивную функцию для построения многомерного массива, а затем я перебираю его, используя многоуровневый foreach для построения меню или чего-либо еще. Мне нужен лучший способ использования PHP SPL.

Я хочу создать полное меню или путь к элементу, например:

category1 -> catgory 2 -> etc.

и создайте сетку, которая содержит уровень категории в каждой строке.

Ответы [ 2 ]

3 голосов
/ 08 мая 2009

Если ваши данные строго иерархичны и выглядят так, я бы порекомендовал метод обхода модифицированного дерева предзаказов для хранения ваших данных.

В Sitepoint есть превосходная статья , в которой обсуждается именно эта проблема. Похоже, вы используете модель списка смежности, которая обсуждается на первой странице, но MPTT гораздо более эффективен для хранения данных такого типа с интенсивным чтением.

Проверьте стр. 2 , чтобы увидеть примеры. Это действительно отличный образец архитектуры.

1 голос
/ 08 мая 2009

Недавно я сделал нечто похожее, используя один запрос и один цикл while. Он использует ссылки для построения древовидных структур данных (массив) с помощью плоской (массив). Там нет SPL, потому что я не чувствовал в этом необходимости. На GitHub есть суть с лучшей цветовой схемой:)

/**
* Each element in the return array has a 'data' key, holding category data,
* like name, and a 'children' key holding its subcategories.
*
* @param resource $resource MySQL resource resulted from mysql_query
* @param string $id_key Name of the 'id' field
* @param string $parent_id_key Name of the 'parent_id' field
* @param boolean $use_cache Use cached result from previous calls. Defaults to TRUE
* @return array
*/
function categories($resource, $id_key, $parent_id_key, $use_cache = true) {
    // Cache the categories in a static local variable. This way, the query
    // will be executed just for the first function call. Subsequent calls
    // will return imediatelly, unless you tell it not to.
    static $tree = array();

    if ($tree && $use_cache) {
        return $tree;
    }

    // Flat representation of the categories for fast retrieval using array
    // keys. Each element will be referenced in the $tree array. This
    // allows to build a tree data structure using a flat one.
    $flat = array();

    // Reset the $tree, in case $use_cache=false in a subsequent call
    $tree = array();

    while ($row = mysql_fetch_object($resource)) {
        $flat[$row->$id_key] = array(
            'data' => $row,
            'children' => array(),
        );

        if (array_key_exists($row->$parent_id_key, $flat)) {
            // Assign children by reference so that possible subcategories of
            // this one will appear in the tree structure ($tree)
            $flat[$row->$parent_id_key]['children'][] =& $flat[$row->$id_key];
        }

        if ($row->$parent_id_key == 0) {
            // Assign by reference for synchronizing $flat with $tree;
            $tree[] =& $flat[$row->$id_key];
        }
    }

    return $tree;
}

Также функция отделена от структуры базы данных. Вам нужно передать ему ресурс mysql_query, строку, представляющую поле id, и строку, представляющую поле parent_id. Плохая часть заключается в том, что он связан с расширением PHP mysql, поскольку использует вызов mysql_fetch_object. Возможно, это можно улучшить.

Некоторым другим преимуществом является то, что он кэширует результат для последующих вызовов, если только вы не скажете ему аннулировать кэш, который является четвертым (логическим) параметром.

Посмотрите, поможет ли это вам.

...