login  Naam:   Wachtwoord: 
Registreer je!
 Tutorials

Tutorials > PHP


Gegevens:
Geschreven door:
Joost
Moeilijkheidsgraad:
Moeilijk
Hits:
8249
Punten:
Aantal punten:
 (4.8)
Aantal stemmen:
5
Stem:
Niet ingelogd
Nota's:
 Lees de nota's (12)
 


Tutorial:

Geavanceerde Arrays

1. Inleiding
2. Multidimensionale arrays sorteren
3. Databasegestuurde Arrays
4. Afsluiting

1. Inleiding

Welkom bij deze tutorial over geavanceerde arrays!
Nog geen idee wat arrays zijn? Neem dan eerst een kijkje bij deze tutorial: Arrays Basics

Oké, laten we maar direct beginnen met het eerste onderwerp: Multidimensionale arrays sorteren!

pijl top
2. Multidimensionale arrays sorteren

Eendimensionale arrays zijn in PHP gemakkelijk te sorteren op index / waarde via de functies sort(), ksort() en andere functies gerelateerd aan die twee.
Maar hoe kunnen we nu gemakkelijk tweedimensionale arrays sorteren in PHP?

We nemen deze simpele tweedimensionale array:

<?php

$users 
= array(
    
=> array(
        
"naam" => "Joel",
        
"score" => 100
    
),
    
=> array(
        
"naam" => "Medieval",
        
"score" => 50
    
),
    
=> array(
        
"naam" => "titjes",
        
"score" => 75
    
)
);

?>

Hoe kunnen we nou eigenlijk de array sorteren op de score die bij elke persoon hoort? Daarvoor hebben we de PHP functie uasort() voor nodig, en een eigen geschreven functie.
We kunnen ook de functies usort() of uksort() gebruiken, maar usort() sorteert op waarden en houdt geen sleutels, en uksort() sorteert op basis van sleutels.
In deze tutorial gebruiken we echter alleen uasort().

We schrijven eerst onze eigen functie:
<?php

function sortScore($x$y){
    return(
$x['score'] < $y['score']);
}

?>
Dat is al genoeg. Later zal ik erop ingaan hoe de functie werkt.
Nu gaan we hem in combinatie met uasort gebruiken om de array te sorteren:
<?php

$users 
= array(
    
=> array(
        
"naam" => "Joel",
        
"score" => 100
    
),
    
=> array(
        
"naam" => "Medieval",
        
"score" => 50
    
),
    
=> array(
        
"naam" => "titjes",
        
"score" => 75
    
)
);


function 
sortScore($x$y){
    return(
$x['score'] < $y['score']);
}

echo 
'Oorspronkelijke array: <pre>'.print_r($users 1).'</pre>';
uasort($users'sortScore');
echo 
'Gesorteerde array: <pre>'.print_r($users 1).'</pre>';
?>

Na het uitvoeren van deze code staan deze arrays op je scherm:

Oorspronkelijke Array Gesorteerde Array
Array
(
    [1] => Array
       (
         [naam] => Joel
         [score] => 100
       )
    [2] => Array
       (
         [naam] => Medieval
         [score] => 50
       )
    [3] => Array
       (
         [naam] => titjes
         [score] => 75
       )
)
Array
(
    [1] => Array
       (
         [naam] => Joel
         [score] => 100
       )
    [3] => Array
       (
         [naam] => titjes
         [score] => 75
       )
    [2] => Array
       (
         [naam] => Medieval
         [score] => 50
       )
)

Voíla, aflopend gesorteerd op score!
Wanneer je degene met de laagste score nu bovenaan zou willen hebben, moet je de < in de functie sortScore() veranderen in >.

Zoals belooft, ga ik nu uitleggen wat de functie sortScore() doet.
De functie vergelijkt alle opgegeven keys ( $x['score'] ), en zet ze daarna opnieuw in de array.
Na een kleine aanpassing van de functie, wordt het duidelijk hoe hij werkt:

<?php

function sortScore($x$y){
    
    static 
$i 0;
    
$i++;
    
    echo 
'Vergelijking '.$i.': '.$x['score'].' vs '.$y['score'].'<br>';
    return(
$x['score'] < $y['score']);
}

?>

Let hierbij op het keyword static. Zonder deze zou $i telkens de waarde 1 hebben, terwijl we willen dat hij verhoogt.
Na de functie te hebben veranderd, komt er naast je 2 arrays nog dit bij:

Vergelijking 1: 50 vs 100
Vergelijking 2: 75 vs 50
Vergelijking 3: 100 vs 75

Je ziet het. Eerst wordt Joel met Medieval vergeleken, daarna Medieval met titjes, en daarna titjes met Joel.
Op basis daarvan wordt de array opnieuw gesorteerd.

De functie om te sorteren op naam komt sterk overeen met de functie om te sorteren op score:

<?php

function sortNaam($x$y){
    return 
strcasecmp($x['naam'], $y['naam']);
}

?>

Let er wel op dat deze functie geen andere array zal teruggeven, omdat de array al op naam gesorteerd is.
Wil je van Z-A sorteren, dan moet je de x en de y omwisselen.

pijl top
3. Databasegestuurde Arrays

Om wat meer duidelijkheid hierin te geven, gebruiken we als model een reactie systeem.
Hierbij kunnen bezoekers reageren op een nieuwsbericht, maar ook reageren op elkaars bericht.
Je kan je dit voorstellen als een soort boomstructuur. Een boomstructuur heeft een geneste structuur.

We gebruiken alleen voor deze tutorial het weergeven van de reacties.
Ik zal ook nog kort uitleggen hoe je de INSERT query moet samenstellen wanneer iemand op een andere reactie reageert.

Eerst de database. Ik heb er een samengesteld die nuttig genoeg is voor deze tutorial:
reactie_id ouder_id reactor bericht
1 0 Medieval Wat een onzin!
2 1 Joel Ik ben het eigenlijk wel met hem eens!
3 2 titjes Ik niet!
4 0 marten Ik ben het wel met hem eens, want....!
5 1 extor Ook nog enige argumentatie Medieval?!
6 5 Medieval Nou kijk, .......!
7 0 Rens Het bericht doet me denken aan...!
8 7 pieterc Hoe kom je daar nou bij? Dat is iets heel anders!!
9 5 vinTage Hij beargumenteerd het toch als de beste?!

Hierbij verwijst ouder_id naar een reactie_id, waarop gereageerd is.
We willen de reacties in de database in een mooie geneste boomstructuur weergeven:
  • 1. Medieval - Wat een onzin!
    • 2. Joel - Ik ben het wel met hem eens!
      • 3. titjes - Ik niet!
    • 5. extor - Ook nog enige argumentatie Medieval?!
      • 6. Medieval - Nou kijk, .....!
      • 9. vinTage - Hij beargumenteerd het toch als de beste?!
  • 4. Marten - Ik ben het wel met hem eens, want....!
  • 7. Rens - Het bericht doet me denken aan....!
    • 8. pieterc - Hoe kom je daar nou bij? Dat is iets heel anders!
Maar hoe doen we dat nou?
Allereerst zullen we even alle reacties selecteren.
<?php

$query 
mysql_query("SELECT * FROM `reacties` ORDER BY `reactie_id` ASC") or die(mysql_error());

while(list(
$reactie_id$parent_id$reactor$bericht) = mysql_fetch_array($query) ){
    
printf("%d. %s : %s<br>"$reactie_id$reactor$bericht); 


?>

We lezen de array uit met list() én mysql_fetch_array().
Het is belangrijk dat je laatste functie gebruikt, met mysql_fetch_assoc zal het niet werken.

Verder gebruiken we printf() in plaats van echo().
printf() is een stuk overzichtelijker dan echo, zeker bij langere stukken tekst.
Je hebt ermee de mogelijkheid om variabelen niet met een ". erin te zetten, maar overzichtelijk als argument in de functie.
De uitleg van php.net vind je onder sprintf().
Deze functie doet vrijwel hetzelfde als printf(), alleen retourneert ze hem in plaats van weergeven.
Dat kan handig zijn als je SQL-queries moet maken die veel variabelen nodig heeft.

Nu weer verder met ons reactiesysteem.
We hebben de reacties nu alleen nog niet zo mooi geselecteerd zoals we willen.
Daarvoor hebben we recursie nodig.
Om dat te bereiken gaan we eerst de selectie in een array zetten:

<?php

$query 
mysql_query("SELECT * FROM `reacties` ORDER BY `reactie_id` ASC") or die(mysql_error());

$reacties = array();

while(list(
$reactie_id$ouder_id$reactor$bericht) = mysql_fetch_array($query) ){
    
$reacties[$ouder_id][$reactie_id]['bericht'] = $bericht;
    
$reacties[$ouder_id][$reactie_id]['reactor'] = $reactor;
}

?>

Je ziet dat we nu een drie dimensionale array hebben.
Je kan met echo '<pre>'.print_r($reacties, 1).'</pre>'; in de browser testen hoe het eruit ziet.
De output daarvan is een beetje teveel om hier te plaatsen.

We gaan nu een functie schrijven die deze array uitleest een weergeeft in de bedoelde vorm door middel van recursie:

<?php

$query 
mysql_query("SELECT * FROM `reacties` ORDER BY `reactie_id` ASC") or die(mysql_error());

$reacties = array();

while(list(
$reactie_id$ouder_id$reactor$bericht) = mysql_fetch_array($query) ){
    
$reacties[$ouder_id][$reactie_id]['bericht'] = $bericht;
    
$reacties[$ouder_id][$reactie_id]['reactor'] = $reactor;
}

function 
showReacties($ouder) {  // Functie accepteert 1 argument: een array
    
    
global $reacties// de reacties ophalen
    
    
echo '<ul>'// lijst starten
    
    
foreach($ouder AS $reactie_id => $reactieData){ // de ingevoerde array foreachen. reactie_id => reactieData
        
        /*
        $reactieData = array
        keys: reactor, bericht
        */
        
        
echo '<li>'// Geef reactie weer
        
        
printf("%d. %s : %s"$reactie_id$reactieData['reactor'], $reactieData['bericht']);
        
        
        
/* 
        Hier start de recursie.
        Is er gereageerd op deze reactie?
        */
        
if(isset($reacties[$reactie_id])){
            
// Zoja, roep deze functie nog een keer aan.
            
showReacties($reacties[$reactie_id]);
        }
        
        echo 
'</li>'// einde weergave van de reactie
        
    
// einde foreach
    
    
echo '</ul>'// einde lijst
    
// einde functie

/* We starten de functie met het ouder_id 0, wat betekent dat er niet op een andere reactie is gereageerd. */
showReacties($reacties[0]);


?>

En met deze code worden de reacties weergegeven zoals bedoelt!
Er staat een hoop commentaar in de functie zelf, ik denk dat je er dan wel uit moet kunnen komen.

Let vooral op het gedeelte van de recursie. Het is eigenlijk niets anders dan de functie opnieuw aanroepen, alleen dan in een diepere dimensie.
Je zou recursie dan ook kunnen omschrijven als een proces dat tot onzekere hoogte moet worden herhaald.
Zo moet een script dat directories doorzoekt een onbekend aantal onderliggende mappen doorzoeken.
Een array kan ook goed een onbekend aantal dimensies hebben.

Je start de recursie in ons voorbeeld bij ouder_id = 0, de hoogste dimensie.


Zoals belooft zal ik ook nog uitleggen hoe je hier een reactiesysteem van zou kunnen maken.
Het enige waar je dan op moet letten, is dat je als ouder_id het reactie_id van de reactie waar op wordt gereageerd meegeeft.
Wordt er niet op een andere reactie gereageerd, moet je als ouder_id 0 meegeven.
Voor de rest verschilt het niet erg veel van een 'gewoon' reactiesysteem.

pijl top
4. Afsluiting

Zo, we zijn er weer doorheen!
Laten we even opsommen wat we hebben behandeld:
  • Multidimensionale arrays sorteren met uasort() en een eigen functie.
  • Het uitlezen van een databaseselectie met list().
  • Het gebruiken van printf() en sprintf().
  • Geneste structuren.
  • Recursie.
Ik hoop dat je er wat van hebt geleerd, en dat je weer verder bent in je PHP vaardigheden!

Wanneer je nog vragen over deze tutorial hebt en/of je vindt dat er nog iets bij moet: plaats een nota!

Medieval

pijl top

« Vorige tutorial : Gegevensvalidatie Volgende tutorial : Rechten beheren »

© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.016s