Hierarchia kategorii (PHP / MySQL)
Staram się umieścić wszystkie moje kategorie i podkategorie z bazy danych MySQL w hierarchii:
Mój wynik powinien być taki (tylko przykład):
- Kat A
- Sub-Cat 1
- Sub_Sub_Cat 1
- Sub_Sub_Cat 2
- Sub_Cat 2
- Kat B
- Kat C
- ...
Kod MySQL:
CREATE TABLE IF NOT EXISTS `categories` (
`category_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'for sub-categories'
PRIMARY KEY (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
Po prostu, jak można go uzyskać w hirarchii z kody PHP ?
5 answers
Używając modelu listy przylegającej, możesz wygenerować strukturę w jednym przejściu.
Wzięte z One Pass Parent-Child Array Structure (Sep 2007; przez Nate Weiner):
$refs = array();
$list = array();
$sql = "SELECT item_id, parent_id, name FROM items ORDER BY name";
/** @var $pdo \PDO */
$result = $pdo->query($sql);
foreach ($result as $row)
{
$ref = & $refs[$row['item_id']];
$ref['parent_id'] = $row['parent_id'];
$ref['name'] = $row['name'];
if ($row['parent_id'] == 0)
{
$list[$row['item_id']] = & $ref;
}
else
{
$refs[$row['parent_id']]['children'][$row['item_id']] = & $ref;
}
}
Z linkowanego artykułu, oto fragment do utworzenia listy do wyjścia. Jest rekurencyjny, jeśli jest potomek dla węzła, wywołuje się ponownie, aby zbudować poddrzewo.
function toUL(array $array)
{
$html = '<ul>' . PHP_EOL;
foreach ($array as $value)
{
$html .= '<li>' . $value['name'];
if (!empty($value['children']))
{
$html .= toUL($value['children']);
}
$html .= '</li>' . PHP_EOL;
}
$html .= '</ul>' . PHP_EOL;
return $html;
}
Podobne Pytanie:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:35
Mam nowy pomysł, myślę, że będzie miło. Chodzi o to, że: w kolumnie category_parent wstawimy odniesienie do wszystkich rodziców tego węzła.
+----+----------------------+-----------------+ | id | category_name | hierarchy | +----+----------------------+-----------------+ | 1 | cat1 | 1 | +----+----------------------+-----------------+ | 2 | cat2 | 2 | +----+----------------------+-----------------+ | 3 | cat3 | 3 | +----+----------------------+-----------------+ | 4 | subcat1_1 | 1-4 | +----+----------------------+-----------------+ | 5 | subcat1_2 | 1-5 | +----+----------------------+-----------------+ | 6 | subsubcat1_1 | 1-4-6 | +----+----------------------+-----------------+ | 7 | subsubcat1_2 | 1-4-7 | +----+----------------------+-----------------+ | 8 | subsubcat1_3 | 1-4-8 | +----+----------------------+-----------------+ | 9 | subsubcat1_3_1 | 1-4-8-9 | +----+----------------------+-----------------+ | 10 | subsubcat1_3_2 | 1-4-8-10 | +----+----------------------+-----------------+ | 11 | subsubcat1_3_1_1 | 1-4-8-9-11 | +----+----------------------+-----------------+ | 12 | subsubsubcat1_3_1_1 | 1-4-8-9-12 | +----+----------------------+-----------------+ | 13 | subsubsubcat1_3_1_2 | 1-4-8-9-11-13 | +----+----------------------+-----------------+ | 14 | subsubsubcat1_2_1_3 | 1-4-8-9-11-14 | +----+----------------------+-----------------+
Jeśli spojrzysz na moją zaktualizowaną tabelę, zauważysz, że każdy rekord ma link do swoich rodziców, nie tylko bezpośredni, ale także wszystkich rodziców. A do tego zadania zrobiłem jakąś modyfikację do wstawienia do be:
Insert into table_name (category_name, hierarchy) values ('new_name', (concat(parent_hierarch, '-', (SELECT Auto_increment FROM information_schema.tables WHERE table_name='table_name'))))
Teraz pozwala dokonać żądanych zapytań:
1-wszystkie podkategorie samochodów:
select * from table_name where hierarchy like '1-%'
2-jeśli need all parent of BLACK wystarczy wpisać:
select * from table_name where hierarchy = '1-4-8-9' or hierarchy = '1-4-8' or hierarchy = '1-4' or hierarchy = '1'
(możesz zbudować to zapytanie z php, dzieląc pole hierarchii na znak' -')
3 - aby zobaczyć wszystkie kategorie, z nadrzędnym poziomem i bezpośrednim:
select *, SUBSTR(hierarchy, 1, (LENGTH(hierarchy) - LENGTH(id) - 1)) as parent, LENGTH(hierarchy) - LENGTH(REPLACE(hierarchy, '-', '')) as level From table_name
+----+----------------------+-----------------+-----------+--------+ | id | category name | hierarchy | parent | level | +----+----------------------+-----------------+-----------+--------+ | 1 | cat1 | 1 | | 0 | +----+----------------------+-----------------+-----------+--------+ | 2 | cat2 | 2 | | 0 | +----+----------------------+-----------------+-----------+--------+ | 3 | cat3 | 3 | | 0 | +----+----------------------+-----------------+-----------+--------+ | 4 | subcat1_1 | 1-4 | 1 | 1 | +----+----------------------+-----------------+-----------+--------+ | 5 | subcat1_2 | 1-5 | 1 | 1 | +----+----------------------+-----------------+-----------+--------+ | 6 | subsubcat1_1 | 1-4-6 | 1-4 | 2 | +----+----------------------+-----------------+-----------+--------+ | 7 | subsubcat1_2 | 1-4-7 | 1-4 | 2 | +----+----------------------+-----------------+-----------+--------+ | 8 | subsubcat1_3 | 1-4-8 | 1-4 | 2 | +----+----------------------+-----------------+-----------+--------+ | 9 | subsubcat1_3_1 | 1-4-8-9 | 1-4-8 | 3 | +----+----------------------+-----------------+-----------+--------+ | 10 | subsubcat1_3_2 | 1-4-8-10 | 1-4-8 | 3 | +----+----------------------+-----------------+-----------+--------+ | 11 | subsubcat1_3_1_1 | 1-4-8-9-11 | 1-4-8-9 | 4 | +----+----------------------+-----------------+-----------+--------+ | 12 | subsubsubcat1_3_1_1 | 1-4-8-9-12 | 1-4-8-9 | 4 | +----+----------------------+-----------------+-----------+--------+ | 13 | subsubsubcat1_3_1_2 | 1-4-8-9-11-13 |1-4-8-9-11 | 5 | +----+----------------------+-----------------+-----------+--------+ | 14 | subsubsubcat1_2_1_3 | 1-4-8-9-11-14 |1-4-8-9-11 | 5 | +----+----------------------+-----------------+-----------+--------+To nowy pomysł i wymaga poprawy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-13 18:40:41
@Amnon Twój kod działa idealnie. Po prostu Przetestowałem go za pomocą CodeIgniter i zadziałało jak urok. Oto działający kod, jeśli ktoś go potrzebuje:
<?php
function disTree($all_cats) {
$tree = array();
foreach ($all_cats as $cat)
{
$pid = $cat->parent_id;
$id = $cat->cat_id;
$name = $cat->cat_name;
// Create or add child information to the parent node
if (isset($tree[$pid]))
// a node for the parent exists
// add another child id to this parent
$tree[$pid]["children"][] = $id;
else
// create the first child to this parent
$tree[$pid] = array("children"=>array($id));
// Create or add name information for current node
if (isset($tree[$id]))
// a node for the id exists:
// set the name of current node
$tree[$id]["name"] = $name;
else
// create the current node and give it a name
$tree[$id] = array( "name"=>$name );
}
return $tree;
}
function toUL($tree, $id, $html){
$html .= '<ul>'.PHP_EOL;
if (isset($tree[$id]['name']))
$html .= '<li>' . $tree[$id]['name'];
if (isset($tree[$id]['children']))
{
$arChildren = &$tree[$id]['children'];
$len = count($arChildren);
for ($i=0; $i<$len; $i++) {
$html .= toUL($tree, $arChildren[$i], "");
}
$html .= '</li>'.PHP_EOL;
}
$html .= '</ul>'.PHP_EOL;
return $html;
}
$tree = disTree($all_cats);
// Display the tree
echo toUL($tree, 0, "");
?>
Jedyną rzeczą, którą zmieniłem było dodanie własnej tablicy ($all_cats).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-29 02:37:05
Wypróbuj następujący kod
//Połącz się z mysql i wybierz db
$conn = mysqli_connect('localhost', 'user', 'password','database');
if( !empty($conn->connect_errno)) die("Error " . mysqli_error($conn));
//call the recursive function to print category listing
category_tree(0);
//Recursive php function
function category_tree($catid){
global $conn;
$sql = "select * from category where parent_id ='".$catid."'";
$result = $conn->query($sql);
while($row = mysqli_fetch_object($result)):
$i = 0;
if ($i == 0) echo '<ul>';
echo '<li>' . $row->cat_name;
category_tree($row->id);
echo '</li>';
$i++;
if ($i > 0) echo '</ul>';
endwhile;
}
//close the connection
mysqli_close($conn);
?>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-15 05:04:01
Jest inny sposób na osiągnięcie tego samego efektu, który uważam za nieco łatwiejszy do naśladowania (bez triku referencyjnego). Tworzysz drzewo dodając odpowiednie informacje do bieżącego węzła i do jego rodzica (Załóżmy, że foreach iteruje nad zwracanymi wierszami z zapytania SQL):
$tree = array();
foreach ($query->result() as $row)
{
$pid = $row->parent_id;
$id = $row->id;
$name = $row->name;
// Create or add child information to the parent node
if (isset($tree[$pid]))
// a node for the parent exists
// add another child id to this parent
$tree[$pid]["children"][] = $id;
else
// create the first child to this parent
$tree[$pid] = array("children"=>array($id));
// Create or add name information for current node
if (isset($tree[$id]))
// a node for the id exists:
// set the name of current node
$tree[$id]["name"] = $name;
else
// create the current node and give it a name
$tree[$id] = array( "name"=>$name );
}
return $tree;
I wyświetlenie drzewa:
function toUL($tree, $id, $html){
$html .= '<ul>'.PHP_EOL;
if (isset($tree[$id]['name']))
$html .= '<li>' . $tree[$id]['name'];
if (isset($tree[$id]['children']))
{
$arChildren = &$tree[$id]['children'];
$len = count($arChildren);
for ($i=0; $i<$len; $i++) {
$html .= toUL($tree, $arChildren[$i], "");
}
$html .= '</li>'.PHP_EOL;
}
$html .= '</ul>'.PHP_EOL;
return $html;
}
// Display the tree
echo toUL($tree, 0, "");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-25 00:27:05