Boomstructuur mysqli moeilijker dan ik dacht

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Dimitri Velghe

Dimitri Velghe

06/08/2018 09:23:22
Quote Anchor link
Ik slaag er niet in om een "boomstructuur" te laten werken in PHP7

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)
PHP script in nieuw venster Selecteer het PHP script
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
<?
$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>
    '
;
    }

 ?>
 
PHP hulp

PHP hulp

14/12/2018 17:12:32
 
- Ariën -
Beheerder

- Ariën -

06/08/2018 11:37:20
Quote Anchor link
Ik zie niet echt een reden waarom het in PHP 7 niet zou werken?

Heb je al je foutmeldingen bovenaan je script aangezet met:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
error_reporting(E_ALL);
ini_set('display_errors',true);
?>


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

Thomas van den Heuvel

06/08/2018 16:08:12
 
Dimitri Velghe

Dimitri Velghe

06/08/2018 16:53:09
Quote Anchor link
Thomas van den Heuvel op 06/08/2018 16:08:12:


hier ga ik eens naar op zoek.... wish me luck
 
Thomas van den Heuvel

Thomas van den Heuvel

06/08/2018 23:34:42
Quote Anchor link
Misschien wordt het in jouw geval iets ingewikkelder omdat het enige verbindende attribuut sh_pt_onderdeel_van lijkt te zijn. Je zult dus alle onderdelen op moeten halen en dan de subboom uitlezen van een specifiek (hoofd)onderdeel.

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.
 
Dimitri Velghe

Dimitri Velghe

07/08/2018 08:19:29
Quote Anchor link
Niet volgens de regels van de kunst vermoed ik ....
Maar wie niet slim is moet creatief zijn zeker :s
Ik loste het zo op.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?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>
'
;
}

?>


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.
Gewijzigd op 07/08/2018 10:07:31 door - Ariën -
 
- Ariën -
Beheerder

- Ariën -

07/08/2018 10:08:33
Quote Anchor link
E nnog steeds kostbare queries in een loop?
 
Thomas van den Heuvel

Thomas van den Heuvel

07/08/2018 14:54:04
Quote Anchor link
Deze oplossing is ook nog steeds maar "twee niveau's diep"? Dit werkt zolang een produkt geen sub-sub-subonderdelen heeft.

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
 
Frank Nietbelangrijk

Frank Nietbelangrijk

07/08/2018 23:12:07
Quote Anchor link
sql dump:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
-- 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 */;


voorbeeld:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?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>
Gewijzigd op 07/08/2018 23:15:36 door Frank Nietbelangrijk
 
Thomas van den Heuvel

Thomas van den Heuvel

08/08/2018 00:58:13
Quote Anchor link
Er is mogelijk geen garantie dat de parents zijn toegevoegd voor de children, daarom is het misschien veiliger om eerst alle resultaten op te halen, en dan pas alles aan elkaar te knopen.
Gewijzigd op 08/08/2018 01:07:02 door Thomas van den Heuvel
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.