PHP menu en submenu in dezelfde tabel?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE `menus` (
`id` int(11) NOT NULL,
`menu_name` varchar(32) NOT NULL,
`parent_id` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `menus` (`id`, `menu_name`, `parent_id`) VALUES
(1, 'Home', 0),
(2, 'About us', 0),
(3, 'Services', 0),
(4, 'Contact', 0),
(5, 'Online Service', 3),
(6, 'Home Service', 3);
`id` int(11) NOT NULL,
`menu_name` varchar(32) NOT NULL,
`parent_id` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `menus` (`id`, `menu_name`, `parent_id`) VALUES
(1, 'Home', 0),
(2, 'About us', 0),
(3, 'Services', 0),
(4, 'Contact', 0),
(5, 'Online Service', 3),
(6, 'Home Service', 3);
Op zich klinkt het heel logisch maar ik heb geen idee hoe ik hier mee om moet gaan in mijn Model (query), View (Template) en Controller. Ik werk namelijk via het MVC principe. Kan iemand mij een stap op weg helpen.
Bij voorbaat dank
1) stop de menu items die bij elkaar horen in een array (doe print_r($menu) om te zien wat ik bedoel)
2) maak een recursive functie die zichzelf herhaaldelijke keren aanroept en zo het menu maakt
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?php
/*
* example data
*/
$data = array(
array(
'id' => 1,
'name' => 'homepage',
'parent' => 0
),
array(
'id' => 2,
'name' => 'About',
'parent' => 0
),
array(
'id' => 3,
'name' => 'Services',
'parent' => 0
),
array(
'id' => 4,
'name' => 'Contact',
'parent' => 0
),
array(
'id' => 5,
'name' => 'Online Service',
'parent' => 3
),
array(
'id' => 6,
'name' => 'Home Service',
'parent' => 3
),
array(
'id' => 7,
'name' => 'test',
'parent' => 6
),
);
$menu = array();
/*
* use array keys to sort the menu items
*/
foreach($data as $item)
{
$menu[$item['parent']][] = $item;
}
// print_r($menu);
echo buildMenu($menu);
/*
* Recursive function that creates submenus in other submenus
*/
function buildMenu($menu, $key = 0)
{
$html = '<ul>' . "\n";
foreach($menu[$key] as $item)
{
$html .= '<li>' . $item['name'];
if(isset($menu[$item['id']])) {
$html .= buildMenu($menu, $item['id']);
}
$html .= '</li>' . "\n";
}
$html .= '</ul>' . "\n";
return $html;
}
?>
/*
* example data
*/
$data = array(
array(
'id' => 1,
'name' => 'homepage',
'parent' => 0
),
array(
'id' => 2,
'name' => 'About',
'parent' => 0
),
array(
'id' => 3,
'name' => 'Services',
'parent' => 0
),
array(
'id' => 4,
'name' => 'Contact',
'parent' => 0
),
array(
'id' => 5,
'name' => 'Online Service',
'parent' => 3
),
array(
'id' => 6,
'name' => 'Home Service',
'parent' => 3
),
array(
'id' => 7,
'name' => 'test',
'parent' => 6
),
);
$menu = array();
/*
* use array keys to sort the menu items
*/
foreach($data as $item)
{
$menu[$item['parent']][] = $item;
}
// print_r($menu);
echo buildMenu($menu);
/*
* Recursive function that creates submenus in other submenus
*/
function buildMenu($menu, $key = 0)
{
$html = '<ul>' . "\n";
foreach($menu[$key] as $item)
{
$html .= '<li>' . $item['name'];
if(isset($menu[$item['id']])) {
$html .= buildMenu($menu, $item['id']);
}
$html .= '</li>' . "\n";
}
$html .= '</ul>' . "\n";
return $html;
}
?>
Hartelijk bedankt voor de reactie. Dat ziet er logisch uit. Maar hoe query ik de database?
Het probleem is dat, zoals ik al aangaf via MVC methode werk. Dus ik heb dit in mijn Model
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
public function get_menu()
{
$sql = "SELECT *
FROM menu";
$stmt = $this->pdo->query($sql);
return $stmt->fetchAll();
}
{
$sql = "SELECT *
FROM menu";
$stmt = $this->pdo->query($sql);
return $stmt->fetchAll();
}
Dit pik ik op in de Controller:
en verstuur dit naar de Vieuw:
Met andere woorden, waar jij de opmaak in je functie(s) hebt doe ik dat normaal gesproken in de View:
En op dit punt weet ik niet hoe ik jou methode hierin zou moeten verwerken.
De MVC methode is enkel bedoeld om verantwoordelijkheden onder te verdelen waardoor je programma beter gestructureerd wordt.
Het renderen van de menu items zou ik niet in de view doen (als uitzondering op de rest) vanwege de complexe geneste structuur. In plaats daarvan zou je je eigen class moeten bouwen die meer opties biedt dan mijn voorbeeldje. Minimaal zou je in je data ook een css-class mee moeten kunnen geven en natuurlijk ook de link.
Maar je kunt ook nog denken aan een icon, een "active" menu-item en aan disabled menu items :-)
In je controller zou je dan iets kunnen doen als
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
$menu = new MyCustomMenu(); // je eigen class
$menu->initialize($this->page->get_menu());
$this->render('header', array(
'menu' => $menu
));
?>
$menu = new MyCustomMenu(); // je eigen class
$menu->initialize($this->page->get_menu());
$this->render('header', array(
'menu' => $menu
));
?>
en in de view zou je dan kunnen doen:
Toevoeging op 23/06/2017 23:22:37:
Voorzetje voor MyCustomMenu:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
class MyCustomMenu
{
protected $menu;
public function initialize($menu_items)
{
foreach($menu_items as $item)
{
$this->menu[$item['parent']][] = $item;
}
return $this;
}
public function render()
{
return $this->buildMenu($this->menu);
}
/*
* Recursive function that creates submenus in other submenus
*/
protected function buildMenu($menu, $key = 0)
{
$html = '<ul>' . "\n";
foreach($menu[$key] as $item)
{
$html .= '<li>' . $item['name'];
if(isset($menu[$item['id']])) {
$html .= $this->buildMenu($menu, $item['id']);
}
$html .= '</li>' . "\n";
}
$html .= '</ul>' . "\n";
return $html;
}
}
class MyCustomMenu
{
protected $menu;
public function initialize($menu_items)
{
foreach($menu_items as $item)
{
$this->menu[$item['parent']][] = $item;
}
return $this;
}
public function render()
{
return $this->buildMenu($this->menu);
}
/*
* Recursive function that creates submenus in other submenus
*/
protected function buildMenu($menu, $key = 0)
{
$html = '<ul>' . "\n";
foreach($menu[$key] as $item)
{
$html .= '<li>' . $item['name'];
if(isset($menu[$item['id']])) {
$html .= $this->buildMenu($menu, $item['id']);
}
$html .= '</li>' . "\n";
}
$html .= '</ul>' . "\n";
return $html;
}
}
Gewijzigd op 23/06/2017 23:49:14 door Frank Nietbelangrijk
Hoi Frank, wederom hartelijk bedankt voor de input. Ik ga hiermee aan de slag
Sorry voor een beetje late reactie. Afgelopen week in de lappemand gelegen (snip en snip verkouden). Even terugkomend op deze kwestie. Er zijn een aantal dingen die mij verwarren. Allereerst je hebt het over een complexe geneste structuur, maar zo complex is het eigenlijk toch niet. Er zijn twee levels. 1 met parent_id = NULL en 1 met parent_id = 2 dan wel 3. Ik heb jou methode proberen na te maken in de voor mij bekende werkwijze:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public function get_menu_items($lang)
{
$sql = "SELECT *
FROM menu
WHERE language_abbr = ?";
$items = $this->pdo->prepare($sql);
$items->execute(array($lang));
$menu_items = array();
foreach ($items as $item) {
if (!isset($menu_items[$item['parent_id']])) {
$menu_items[$item['parent_id']] = array();
}
$menu_items[$item['parent_id']][] = $item;
}
return $menu_items;
}
{
$sql = "SELECT *
FROM menu
WHERE language_abbr = ?";
$items = $this->pdo->prepare($sql);
$items->execute(array($lang));
$menu_items = array();
foreach ($items as $item) {
if (!isset($menu_items[$item['parent_id']])) {
$menu_items[$item['parent_id']] = array();
}
$menu_items[$item['parent_id']][] = $item;
}
return $menu_items;
}
en dit in de View:
Code (php)
1
2
3
4
5
2
3
4
5
<ul>
<?php $parent_id = NULL; foreach ($menu_items[$parent_id] as $item):?>
<li><a href="#"><?= $item['navigation_name']; ?></a></li>
<?php endforeach; ?>
</ul>
<?php $parent_id = NULL; foreach ($menu_items[$parent_id] as $item):?>
<li><a href="#"><?= $item['navigation_name']; ?></a></li>
<?php endforeach; ?>
</ul>
Dit geeft me in principe al de eerste laag (parent_id = NULL). Er is een andere reden waarom ik het een en ander wel graag in de View doe en wel om de reden dat de site Bootstrap based is dus ik ook nog wel wat classes etc kwijt moet (dropdown etc).
Ben alleen niet zeker hoe ik de tweede laag (sub menus) moet genereren
Gewijzigd op 19/07/2017 07:44:10 door Donald Boers