Boomstructuur mysqli moeilijker dan ik dacht
Ik wil namelijk mijn menu dynamisch houden en dat lukte in php5.6
Maar om de een of andere reden wil deze niet in php7
De afzonderlijke queries werken echter wel....
maar als ik de geneste query wil uitvoeren dan toont hij enkel de eerste parent categorie.
Doe ik de geneste query niet dan toont hij wel alle parent categoriën
is daar een reden voor?
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
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
<?
$sql_q_salon ="SELECT
*
FROM
shop_produkt_type
WHERE
sh_pt_onderdeel_van = 9
ORDER BY
sh_pt_volgorde";
$r_list = mysqli_query($con, $sql_q_salon);
while($salon = mysqli_fetch_assoc($r_list))
{
echo'<ul ';
echo'class="column" ';
echo'>
<li class="column-title">'.$salon['sh_pt_naam_nl'].' </li>
' ;
// als ik de volgende query uitschakel dan heeft hij wel alle bovenliggende categorien weer, schakel ik deze in dan heeft hij enkel de regels van de eerste categorie weer
$q_list ="SELECT
*
FROM
shop_produkt_type
WHERE
sh_pt_onderdeel_van = '".$salon['sh_pt_id']."'
ORDER BY
sh_pt_volgorde
";
$r_list = mysqli_query($con, $q_list) or die (mysqli_error());
while($list = mysqli_fetch_assoc($r_list))
{
echo'<li><a href="/?view=category&id='.$list['sh_pt_id'].'">'.$list['sh_pt_naam_nl'].'</a></li>
';
}
echo'</ul>
';
}
?>
$sql_q_salon ="SELECT
*
FROM
shop_produkt_type
WHERE
sh_pt_onderdeel_van = 9
ORDER BY
sh_pt_volgorde";
$r_list = mysqli_query($con, $sql_q_salon);
while($salon = mysqli_fetch_assoc($r_list))
{
echo'<ul ';
echo'class="column" ';
echo'>
<li class="column-title">'.$salon['sh_pt_naam_nl'].' </li>
' ;
// als ik de volgende query uitschakel dan heeft hij wel alle bovenliggende categorien weer, schakel ik deze in dan heeft hij enkel de regels van de eerste categorie weer
$q_list ="SELECT
*
FROM
shop_produkt_type
WHERE
sh_pt_onderdeel_van = '".$salon['sh_pt_id']."'
ORDER BY
sh_pt_volgorde
";
$r_list = mysqli_query($con, $q_list) or die (mysqli_error());
while($list = mysqli_fetch_assoc($r_list))
{
echo'<li><a href="/?view=category&id='.$list['sh_pt_id'].'">'.$list['sh_pt_naam_nl'].'</a></li>
';
}
echo'</ul>
';
}
?>
Heb je al je foutmeldingen bovenaan je script aangezet met:
Verder is een while-loop in een while-loop niet echt bevorderlijk. Ik zou meer aan een goede recursie denken, omdat je queries spaarzaam moet gebruiken.
Thomas van den Heuvel op 06/08/2018 16:08:12:
hier ga ik eens naar op zoek.... wish me luck
En dit gaat waarschijnlijk alleen (direct) werken als de subonderdelen zijn toegevoegd na de hoofdonderdelen, zodat een subonderdeel altijd een hoger id heeft dan het hoofdonderdeel. Je kunt dan oplopend sorteren op onderdeel-id en dan kun je in PHP een soort van geneste datastructuur uitrollen.
Als hier niet aan voldaan is is er nog geen kind overboord maar dan wordt het bouwen van de boom waarschijnlijk wel wat lastiger (kun je in ieder geval niet meer on the fly doen dan waarschijnlijk) omdat de elementen daar dan niet in de goede volgorde gezet kunnen worden.
Vaak zit in bomen een volgorde van elementen van eenzelfde niveau en hebben elementen een voorgeschreven diepte. Deze twee zaken helpen je om zo'n datastructuur sneller op te tuigen. Maar deze hulpstukken zijn dus niet altijd van toepassing. Misschien is het het overwegen waard om van een (geassembleerd) product een aparte boom te maken? Dus elk product heeft een eigen boom? Dan kun je die concepten (volgorde, (en in ieder geval, en in zekere zin, belangrijker de) diepte) weer wel toepassen.
Maar wie niet slim is moet creatief zijn zeker :s
Ik loste het zo op.
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
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
<?php
$teller = 0;
$sql_q_salon ="SELECT
*
FROM
shop_produkt_type
WHERE
sh_pt_onderdeel_van = 65
ORDER BY
sh_pt_volgorde";
$r_list = mysqli_query($con, $sql_q_salon);
while($salon = mysqli_fetch_assoc($r_list))
{
$parent[''.$teller.''] = array(
'id' => $salon['sh_pt_id'],
'volgorde' => $salon['sh_pt_volgorde'],
'titel' => $salon['sh_pt_naam_'.$_SESSION['lg'].'']);
$teller++;
}
foreach($parent AS $column)
{
echo'<ul class="column" >
<li class="column-title">'.$column['titel'].'</li>
' ;
$q_list ="SELECT
*
FROM
shop_produkt_type
WHERE
sh_pt_onderdeel_van = '".$column['id']."'
";
$r_list = mysqli_query($con, $q_list) or die (mysqli_error());
while($list = mysqli_fetch_assoc($r_list))
{
echo'<li><a href="/?view=category&id='.$list['sh_pt_id'].'">'.$list['sh_pt_naam_'.$_SESSION['lg'].''].'</a></li>
';
}
echo'</ul>
';
}
?>
$teller = 0;
$sql_q_salon ="SELECT
*
FROM
shop_produkt_type
WHERE
sh_pt_onderdeel_van = 65
ORDER BY
sh_pt_volgorde";
$r_list = mysqli_query($con, $sql_q_salon);
while($salon = mysqli_fetch_assoc($r_list))
{
$parent[''.$teller.''] = array(
'id' => $salon['sh_pt_id'],
'volgorde' => $salon['sh_pt_volgorde'],
'titel' => $salon['sh_pt_naam_'.$_SESSION['lg'].'']);
$teller++;
}
foreach($parent AS $column)
{
echo'<ul class="column" >
<li class="column-title">'.$column['titel'].'</li>
' ;
$q_list ="SELECT
*
FROM
shop_produkt_type
WHERE
sh_pt_onderdeel_van = '".$column['id']."'
";
$r_list = mysqli_query($con, $q_list) or die (mysqli_error());
while($list = mysqli_fetch_assoc($r_list))
{
echo'<li><a href="/?view=category&id='.$list['sh_pt_id'].'">'.$list['sh_pt_naam_'.$_SESSION['lg'].''].'</a></li>
';
}
echo'</ul>
';
}
?>
Edit:
Ik heb code-tags geplaatst. Gelieve dit in het vervolg zelf toe te voegen aan je bericht.
Zie ook: Veel gestelde vragen: Welke UBB-codes kan ik gebruiken.
Zie ook: Veel gestelde vragen: Welke UBB-codes kan ik gebruiken.
Gewijzigd op 07/08/2018 10:07:31 door - Ariën -
E nnog steeds kostbare queries in een loop?
Ook hier doe je in wezen wat ik in een andere thread tegen die topicstarter zei: je combineert hier verschillende dingen tegelijkertijd:
- het bouwen van de dataset
- het filteren van de items waarin je geïnteresseerd bent
- het weergeven van de relevante items
Als je dit nu eens opsplitst door:
- alle items op te halen met één query
- je een recursieve PHP-functie bouwt die de relevante items ophaalt (de PHP-kant heeft op dit moment al alle informatie uit de database, er zijn dus geen extra queries meer nodig)
- je (nog) een recursieve PHP-functie schrijft die hier een boom van maakt
De voordelen hiervan zijn:
- je schrijft herbruikbare code, waarbij elk onderdeel een (één) specifieke taak verricht, ik kan mij best voorstellen dat je andere bomen wilt kunnen bouwen en/of wilt kunnen filteren in deze data-structuur
- door deze eenvoud kun je beter het overzicht houden doordat je deze taken splitst (separation of concerns)
- deze aanpak helpt bij het leren om "complexe" problemen op te splitsen in kleinere deelproblemen zodat je stapsgewijs naar een oplossing werkt, in plaats van te pogen om dit rechtstreeks te doen, de volgende keer dat je zoiets doet zul je dan waarschijnlijk weer code op maat moeten schrijven voor dat specifieke probleem en dat is zonde van de tijd
En wat je hier dus effectief doet is het "probleem" overhevelen van de database naar PHP, zoals eerder aangehaald zijn queries redelijk dure operaties, dus hoe minder queries je uitvoert, hoe beter. PHP kan ook een heleboel werk verzetten door wat simpele datastructuren te bouwen in de vorm van (geneste) arrays en wat hulpfuncties.
Gewijzigd op 07/08/2018 15:00:39 door Thomas van den Heuvel
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
82
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
82
-- phpMyAdmin SQL Dump
-- version 4.5.4.1deb2ubuntu2
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Gegenereerd op: 07 aug 2018 om 23:10
-- Serverversie: 10.2.14-MariaDB-10.2.14+maria~xenial
-- PHP-versie: 7.2.6-1+ubuntu16.04.1+deb.sury.org+1
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `test`
--
-- --------------------------------------------------------
--
-- Tabelstructuur voor tabel `boomstructuur`
--
CREATE TABLE `boomstructuur` (
`id` int(11) NOT NULL,
`parent_id` int(11) DEFAULT NULL,
`description` varchar(50) NOT NULL,
`link` varchar(255) DEFAULT NULL,
`rank` int(11) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Gegevens worden gexporteerd voor tabel `boomstructuur`
--
INSERT INTO `boomstructuur` (`id`, `parent_id`, `description`, `link`, `rank`) VALUES
(1, NULL, 'fruit', NULL, 20),
(2, 1, 'appel', NULL, 1),
(3, NULL, 'landen', NULL, 10),
(4, 3, 'nederland', 'http://www.google.nl', 2),
(5, 3, 'Belgie', NULL, 1),
(6, 4, 'Brabant', NULL, 1),
(7, 4, 'Limburg', NULL, 1);
--
-- Indexen voor gexporteerde tabellen
--
--
-- Indexen voor tabel `boomstructuur`
--
ALTER TABLE `boomstructuur`
ADD PRIMARY KEY (`id`),
ADD KEY `parent_id` (`parent_id`);
--
-- AUTO_INCREMENT voor gexporteerde tabellen
--
--
-- AUTO_INCREMENT voor een tabel `boomstructuur`
--
ALTER TABLE `boomstructuur`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;
--
-- Beperkingen voor gexporteerde tabellen
--
--
-- Beperkingen voor tabel `boomstructuur`
--
ALTER TABLE `boomstructuur`
ADD CONSTRAINT `boomstructuur_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `boomstructuur` (`id`);
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
-- version 4.5.4.1deb2ubuntu2
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Gegenereerd op: 07 aug 2018 om 23:10
-- Serverversie: 10.2.14-MariaDB-10.2.14+maria~xenial
-- PHP-versie: 7.2.6-1+ubuntu16.04.1+deb.sury.org+1
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `test`
--
-- --------------------------------------------------------
--
-- Tabelstructuur voor tabel `boomstructuur`
--
CREATE TABLE `boomstructuur` (
`id` int(11) NOT NULL,
`parent_id` int(11) DEFAULT NULL,
`description` varchar(50) NOT NULL,
`link` varchar(255) DEFAULT NULL,
`rank` int(11) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Gegevens worden gexporteerd voor tabel `boomstructuur`
--
INSERT INTO `boomstructuur` (`id`, `parent_id`, `description`, `link`, `rank`) VALUES
(1, NULL, 'fruit', NULL, 20),
(2, 1, 'appel', NULL, 1),
(3, NULL, 'landen', NULL, 10),
(4, 3, 'nederland', 'http://www.google.nl', 2),
(5, 3, 'Belgie', NULL, 1),
(6, 4, 'Brabant', NULL, 1),
(7, 4, 'Limburg', NULL, 1);
--
-- Indexen voor gexporteerde tabellen
--
--
-- Indexen voor tabel `boomstructuur`
--
ALTER TABLE `boomstructuur`
ADD PRIMARY KEY (`id`),
ADD KEY `parent_id` (`parent_id`);
--
-- AUTO_INCREMENT voor gexporteerde tabellen
--
--
-- AUTO_INCREMENT voor een tabel `boomstructuur`
--
ALTER TABLE `boomstructuur`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;
--
-- Beperkingen voor gexporteerde tabellen
--
--
-- Beperkingen voor tabel `boomstructuur`
--
ALTER TABLE `boomstructuur`
ADD CONSTRAINT `boomstructuur_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `boomstructuur` (`id`);
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
voorbeeld:
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
82
83
84
85
86
87
88
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
82
83
84
85
86
87
88
<?php
/*
* Deze recursive functie bouwt een multidimensionale array die precies de structuur van de boom heeft
*/
function buildTree($records, $parentId = NULL)
{
$result = array();
foreach($records as $record)
{
if($record['parent_id'] == $parentId)
{
$record['children'] = buildTree($records, $record['id']);
$result[] = $record;
}
}
return $result;
}
/*
* Deze functie maakt van de multidemensionale array een unsorted list ( <ul> )
*/
function renderList($parent)
{
$html = '';
foreach($parent as $branch)
{
$html .= "<ul>\n<li>";
if($branch['link']) {
$html .= '<a href="' . $branch['link'] . '">' . $branch['description'] . '</a>';
} else {
$html .= $branch['description'];
}
if(count($branch['children']))
{
$html .= "\n";
}
$html .= renderList($branch['children']);
$html .= "</li>\n</ul>\n";
}
return $html;
}
// HIER START DE APPLICATIE
// maak verbinding met de database
$conn = mysqli_connect('127.0.0.1', 'name', 'pass', 'test');
if (!$conn) {
echo "Error: Unable to connect to MySQL." . PHP_EOL;
echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
exit;
}
// Haal alle records op
$result = mysqli_query($conn, 'SELECT id, parent_id, description, link FROM boomstructuur ORDER BY rank ASC');
// fetch alle records in een keer
$array = mysqli_fetch_all($result, MYSQLI_ASSOC);
// maak van de recht toe recht aan array een boom structuur
$boom = buildTree($array);
// maak van de boomstructuur een <ul>...</ul>
$menu = renderList($boom);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mijn Boomstructuur</title>
</head>
<body>
<pre><?php print_r($boom); ?></pre>
<?php echo $menu; ?>
</body>
</html>
/*
* Deze recursive functie bouwt een multidimensionale array die precies de structuur van de boom heeft
*/
function buildTree($records, $parentId = NULL)
{
$result = array();
foreach($records as $record)
{
if($record['parent_id'] == $parentId)
{
$record['children'] = buildTree($records, $record['id']);
$result[] = $record;
}
}
return $result;
}
/*
* Deze functie maakt van de multidemensionale array een unsorted list ( <ul> )
*/
function renderList($parent)
{
$html = '';
foreach($parent as $branch)
{
$html .= "<ul>\n<li>";
if($branch['link']) {
$html .= '<a href="' . $branch['link'] . '">' . $branch['description'] . '</a>';
} else {
$html .= $branch['description'];
}
if(count($branch['children']))
{
$html .= "\n";
}
$html .= renderList($branch['children']);
$html .= "</li>\n</ul>\n";
}
return $html;
}
// HIER START DE APPLICATIE
// maak verbinding met de database
$conn = mysqli_connect('127.0.0.1', 'name', 'pass', 'test');
if (!$conn) {
echo "Error: Unable to connect to MySQL." . PHP_EOL;
echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
exit;
}
// Haal alle records op
$result = mysqli_query($conn, 'SELECT id, parent_id, description, link FROM boomstructuur ORDER BY rank ASC');
// fetch alle records in een keer
$array = mysqli_fetch_all($result, MYSQLI_ASSOC);
// maak van de recht toe recht aan array een boom structuur
$boom = buildTree($array);
// maak van de boomstructuur een <ul>...</ul>
$menu = renderList($boom);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mijn Boomstructuur</title>
</head>
<body>
<pre><?php print_r($boom); ?></pre>
<?php echo $menu; ?>
</body>
</html>
Gewijzigd op 07/08/2018 23:15:36 door Frank Nietbelangrijk
Gewijzigd op 08/08/2018 01:07:02 door Thomas van den Heuvel