|
|||
Inleiding |
|||
Dit hoofdstuk gaat over het winkelmandje. Als een klant aan het bestellen is wil je de bestelde producten nog niet vastleggen in de database voordat de klant zijn bestelling gaat afronden. Tot die tijd moeten wel ergens de voorlopige bestelgegevens worden opgeslagen. Dit gaan we regelen door de $_SESSION variabele te gebruiken. Je weet uit het vorige hoofdstuk al dat je de gegevens van de gebruiker kan opslaan in deze variabele en dat zolang de klant is aangemeld en de browser niet wordt afgesloten deze gegevens beschikbaar blijven. In de vorige hoofdstukken hebben we code ontwikkeld voor de eigenaren van het bedrijf. Producten kunnen daarin worden toegevoegd, bewerkt en verwijderd. Bovendien mag een medewerker dat alleen doen als deze is ingelogd. Maak eerst een nieuwe map klant en kopieer daar de bestanden
index.php, database.php, algemeen.php en product.php heen. Als autorisatie ook al klaar is kopieer je ook index.php en autorisatie.php. In het voorbeeld hieronder is autorisatie nog niet aanwezig. We gaan hier niet voor alles volledig uitgewerkte code geven. Eigen productie is gewenst. Aan het einde van dit hoofdstuk weet je :
|
|||
|
|||
Winkelmand maken |
|||
In index.php plaatsen we acties om de winkelmand aan te maken en te vullen. De functies die deze acties moeten gaan doen plaatsen we in winkelmand.php Op de eerste regel in index.php moet session_start(); komen te staan want net als bij autorisatie moeten we nu bij ieder bezoek onthouden wat er in de winkelmand zit. Staat session_start(); nog niet in index.php voeg die dan toe. Op de volgende regel maken we het winkelmandje. // Als er nog geen winkelwagen aanwezig is maak er dan één if(!isset($_SESSION['winkelwagen'])) { $_SESSION['winkelwagen']=array(); } Je ziet dat we een array gaan gebruiken als winkelwagen. We gebruiken een associatieve rij. Voorbeelden van associatieve rijen zijn o.a. $_GET, $_POST, en $_SESSION. Associatieve rijen bevatten key, value paren waarin de key de index in de rij is en value de waarde van het element in de rij behorende bij index key. Voorbeeld: <?php $Leeftijd=array("Peter"=>"35","Ben"=>"37","Kees"=>"43"); $Leeftijd["John"]=57; echo "Kees is " . $Leeftijd['Peter'] . " jaar oud en John is " . $Leeftijd['John'] . " jaar oud."; ?> Je kunt alle waarden in een associatieve rij als volgt benaderen. <?php $Leeftijd=array("Peter"=>"35","Ben"=>"37","Kees"=>"43"); $Leeftijd["John"]=57; // algemeen $uitvoer=""; foreach($Leeftijd as $key=>$value) { uitvoer .= "Het element met index key=" . $key . " heeft de waarde value=" . $value."<br>"; } // in dit geval met zinvolle naamgeving foreach($Leeftijd as $naam=>$leeftijd) { uitvoer .= "$naam is $leeftijd." jaar oud<br>"; } ?> |
|||
Opdrachten |
|
||
Winkelmand vullen |
|||
In de vorige paragraaf hebben we gezien dat in $_SESSION['winkelwagen'] een associatieve array is aangemaakt die de lijst met bestelde producten tijdelijk moet gaan opslaan. Pas als de klant de bestelling bevestigd moet de inhoud van de array naar de database worden overgezet. Als de productenlijst op de goed manier is aangemaakt is per product een invoerveld voor het aantal dat de klant wil kopen en een bestelknop om deze aan het winkelmandje toe te kunnen voegen. Als op de bestelknop wordt gedrukt moet naar de server niet alleen het aantal maar ook het id van het product worden opgestuurd. Ik neem even aan dat je in het formulier de namen "aantal" en "productid" hebt gebruikt. De functie die achter de bestelknop wordt geplaatst moet dan in ieder geval de volgende code bevatten $aantal=""; $id=""; if(isset($_POST["productid"])) { $id=trim($_POST["productid"]); } if(isset($_POST["aantal"])) { $aantal=trim($_POST["aantal"]); } if( !empty($id) ) { $_SESSION['winkelwagen'][$id]=$aantal; } |
|||
Opdrachten |
|
||
Als de klant een spatie opstuurt, geen getal of een getal kleiner of gelijk aan 0, dan willen we eigenlijk het hele product uit de winkelmand verwijderen. Het volgende voorbeeld doet dit: $aantal=""; $id=""; if(isset($_POST["productid"])) { $id=trim($_POST["productid"]); } if(isset($_POST["aantal"])) { $aantal=(int)trim($_POST["aantal"]); } if( !empty($id) ) { if( is_int($aantal) && $aantal>0 ) { $_SESSION['winkelwagen'][$id]=$aantal; } else { // Verwijder $_SESSION['winkelwagen'][$id] unset($_SESSION['winkelwagen'][$id]); } } |
|
||
Winkelmand tonen |
|||
Er zijn verschillende manieren om de winkelmand te tonen. Je kunt de toonArtikelenLijst als basis gebruiken voor een
nieuwe functie of je kunt de toonArtikelenLijst van een parameter ( function toonArtikelenLijst( $alswinkelwagen ) {...} )
voorzien zodat de uitvoer conditioneel kan worden gemaakt. Wat in ieder geval moet gebeuren is dat we uit de datbase
niet alle maar alleen de producten uit de winkelmand opvragen. Dus niet alleen
MYSQL geeft de mogelijkheid om in de conditie een lijst aan te bieden van te selecteren items. De query
Hoe maak je "WHERE `id` IN ( '12', '15' , '110')" uitgaande van $_SESSION['winkelwagen']? $conditie = ""; if( count($_SESSION['winkelwagen'])>0 ) { $conditie = "WHERE `id` IN ("; $first=true; foreach($_SESSION['winkelwagen'] as $id => $aantal) { if( $first ) $first=false; else $conditie .= ","; $conditie .= "'$id'"; } $conditie .= ")"; } Natuurlijk moeten na het uitvoeren van de query de aantallen van de bestelde producten getoond worden en eventueel weer worden veranderd. Je kunt dan bijvoorbeeld de volgende code gebruiken in de while lus van het maken van de productentabel: $aantal=""; if(isset($_SESSION['winkelwagen'][$id])) $aantal = $_SESSION['winkelwagen'][$id]; |
Opdrachten |
|
|
Order plaatsen |
|||
Een order behoort bij een klant en bevat producten. In de database bevat de order tabel alleen een verwijzing naar de klant. De order_product tabel bevat de koppeling naar de order. Om de order met zijn producten moeten drie dingen gebeuren:
Echter als het plaatsen van de artikelen in de order_product tabel mislukt zitten we in de database opgescheet met een lege order. We moeten er dus voor zorgen dat als dit gebeurd ook de order weer uit de database wordt verwijderd. MySQL regelt dit door gebruik te maken van transacties. Je start een transactie, gaat er onderweg iets mis dan annuleer je die transactie (rollback) anders gaat de transactie door (commit). Een voorbeeld van de benodigde set queries en instructies om een order van klant 1 die de 6 exemplaren van product 1 en 3 exemplaren van product 2. op te slaan is: // $db is een bestaande myqli connectie. // Als alles goed gaat is dit de af tehandelen reeks instructies: $klantid = 1; // Moet natuurlijk het id van de ingelogde klant worden $db->beginTransaction(); //CURRENT_DATE() is een SQL commando om alleen de datum uit het huidige moment te halen. $query1="INSERT INTO `order` (`klantid`,`orderdatum`) VALUES (:klantid,CURRENT_DATE())"; $opdracht = $db->prepare($query1); // bereid de query voor $opdracht->bindParam(':klantid', $klantid); $opdracht->execute(); // voer de query uit //pak de laatst gemaakte order in deze sessie $orderid = $db->lastInsertId(); // prijs van artikel wordt uit de database gehaald met de query // SELECT prijs FROM product WHERE id = '$productid' $query2 ="INSERT INTO `order_product` (`orderid`, `productid`, `aantal`, `prijs`) VALUES ('$orderid', :productid, :aantal,(SELECT prijs FROM product WHERE id = :productid) );"; $opdracht1 = $db->prepare($query2); $opdracht1->bindParam(':productid', $productid); $opdracht1->bindParam(':aantal', $aantal); $productid = 1; // Moet natuurlijk uit het winkelmandje worden gehaald $aantal = 1; // Moet natuurlijk uit het winkelmandje worden gehaald $opdracht1->execute(); $productid = 2; // Moet natuurlijk uit het winkelmandje worden gehaald $aantal =12; // Moet natuurlijk uit het winkelmandje worden gehaald $opdracht1->execute(); echo "Producten geplaatst $orderid Je moet dit weer met een try /catch constuctie coderen. Treedt er een fout op dan moet de statement $db->rollback(); worden uitgevoerd.. Natuurlijk moet dit natuurlijk wel netjes in een functie terecht komen. Je zult dus iets moeten doen als het voorbeeld in PHP en MySQL: invoeren. $query2 moet worden opgebouwd uit de winkelmand op ongeveer de zelfde wijze als $conditie bij het tonen van de winkelmand. Het klantid moet na inloggen uit $_SESSION worden opgehaald. Tenslotte moet de datum de huidige datum worden. |