1
Cursus PHP & MySQL
Informaticaprojecten
Bachelor Toegepaste Informatica
academiejaar 2008 - 2009
Jaar 1 Semester 1 & 2
Groep D
feneX
Voorwoord
Deze cursus PHP & MySQL werd opgesteld door een groep studenten uit het
eerste jaar Toegepaste Informatica aan de Artesis Hogeschool Antwerpen. Dit als
onderdeel van een opdracht voor het vak Informaticaprojecten. Dit jaar wordt er
van de studenten verwacht dat zij zichzelf en de andere studenten binnen hun
groep gedurende het ganse eerste semester vertrouwd maken met PHP en
MySQL.
Er werd getracht dit met behulp van peer-teaching te doen, de verschillende
groepsleden zullen elkaar onderwijzen en elkander helpen de stof te begrijpen en
te leren toepassen.
Aan de hand van de verschillende lessen die we doorheen het eerste semester
gegeven en gevolgd hebben, werd deze cursus opgesteld.
Deze cursus werd geschreven door een negental eerstejaarsstudenten, met
name door Pieter-Jan Beelen, Maarten Casteels, Mathias De Rijke, Jeroen
D‟hulst, Joris Dirickx, Martijn Moreel, Samantha Napier, Nick Quadens en Bart
Vervliet; het moge duidelijk zijn dat deze cursus dus geen allesomvattend
naslagwerk is. Toch hebben wij getracht om de studenten binnen onze groep een
degelijke basiskennis van PHP en MySQL mee te geven. Voor die doeleinden
valt deze cursus dus wel te gebruiken.
Hoofdstuk 1
Inleiding _________________________________________________________________ Cursus PHP & MySQL Groep D
© feneX – Cursus PHP & MySQL p 1
Hoofdstuk 1: Inleiding
1.1 Wat is PHP & MySQL?
PHP is een krachtige server-side scripting taal die onder andere gebruikt wordt
voor het maken van dynamische- en interactieve websites. Het is volledig open
source en werd door en voor webdevelopers ontwikkeld. PHP staat voor PHP:
Hypertext Preprocessor, vroeger stond de afkorting voor Personal Home Page
Tools, maar naarmate de taal evolueerde, heeft men ook de naam aangepast.
PHP is, zoals eerder al aangehaald werd, een server-side scripting taal – meer
hierover later – die binnen HTML-pagina‟s gebruikt kan worden of als gewone
scriptingtaal. Al wordt het vooral gebruikt voor webontwikkeling. Je zou het een
gratis alternatief voor gelijkaardige producten als Microsofts Active Server Pages
(ASP) en Suns Java Server Pages (JSP) kunnen noemen. Dit wil echter in geen
opzicht zeggen dat PHP een flauw afkooksel van eerder genoemde producten is.
In de volgende paragraaf zal snel duidelijk worden waarom dat niet het geval is.
MySQL op zijn beurt is een open source SQL relationeel database management
systeem (RDBMS). Het is dus een database waarin je tal van gegevens kunt
opslaan in tabellen. We gebruiken queries om gegevens uit de database op te
halen, aan te passen, enz. Meer hierover later.
1.2 Waarom PHP & MySQL?
Zoals in de vorige paragraaf reeds aangehaald werd, is PHP niet de enige
scripting taal die je kunt gebruiken. Er zijn een aantal alternatieven zoals ASP en
JSP, al brengt de combinatie van PHP en MySQL toch wel enkele voordelen met
zich mee. Allereerst is PHP volledig open source, wat wil zeggen dat het je vrijwel
niks kost om een server met MySQL en PHP te draaien. Dit staat in schril
contrast met de kosten die gepaard gaan met het hosten van een ASP/SQL- of
een JSP/Oracle server. Even ter vergelijking:
Item ASP/SQL JSP/Oracle PHP/MySQL
Development tools $0 – 2499 $0 – 2000 $0 – 249
Server $999 $0 – 35 000 $0
RDBMS $4999 $15 000 $0 – 220
© feneX – Cursus PHP & MySQL p 2
Een tweede voordeel is dat PHP relatief makkelijk om leren is. In tegenstelling tot
bijvoorbeeld JSP hoef je niet meteen over een diepe kennis van een
onderliggende programmeertaal te beschikken. PHP heeft een relatief simpele
syntax die ook voor „gewone mensen‟ gemakkelijk te begrijpen is.
Nog een groot pluspunt is dat PHP vrijwel volledig cross-platform is. Dit wil
zeggen dat een PHP-server op zo goed als elk systeem perfect zal draaien
(Windows, Unix,…).
Daarenboven is PHP zeer stabiel en snel. Het werkt samen met Apache Server:
die vaak de meest stabiele web server genoemd wordt. De server hoeft slecht
sporadisch te worden herstart, en niet bij elke wijziging van de instellingen.
Voorts verwerkt PHP code zo goed als even snel als ASP en zelfs ettelijke keren
sneller dan JSP of ColdFusion.
1.3 Server-Side Scripting Een concept dat je ook goed moet begrijpen, is dat PHP een server-side scripting
taal is. Dit wil zeggen dat de code vooraf op de server wordt uitgevoerd alvorens
die getoond wordt aan de gebruiker. Dit in tegenstelling tot andere client-side
technologiën die vaak gebruikt worden bij webontwikkeling. HTML-code wordt
bijvoorbeeld volledig door de browser geïnterpreteerd en is dus client-side. CSS
en JavaScript werken op dezelfde manier.
Het feit dat PHP een server-side scripting taal is, zorgt ervoor dat de taal vooral
geschikt is om sites met snel veranderende inhoud, forums en andere
webapplicaties die met databases werken te maken.
© feneX – Cursus PHP & MySQL p 3
1.4 Getting Started
Vooraleer je met PHP aan de slag kunt, zijn er een aantal dingen die je nodig
hebt. Allereerst is het handig dat je over enige basiskennis HTML beschikt.
Gezien PHP binnen HTML-bestanden geschreven wordt, spreekt het uiteraard
voor zich dat een beetje voorkennis van HTML wel van pas zal komen. De invoer
die je gaat gebruiken in je PHP-scripts zal ook aangeleverd worden aan de hand
van HTML-forms. Bijgevolg moet je dus wel in staat zijn om een HTML-form te
schrijven. Meer hierover kom je nog te weten in het volgende hoofdstuk.
Om de PHP-code zelf te schrijven, hebben we uiteraard ook een programma
nodig. Je zou dit simpelweg in kladblok kunnen doen, maar er bestaan natuurlijk
nog een boel andere alternatieven die je het veel makkelijker zullen maken om tot
een duidelijke en gestructureerde code te komen. In deze cursus hebben wij
gekozen om met Dreamweaver te werken. Een tweede optie is om met Microsoft
Expression Web 2 te werken. Beide zijn complete editors die net als Visual
Studio 2008 met een handige IntelliSense functie geleverd worden. Expression
kun je via MSDNAA downloaden, Dreamweaver zul je elders op de kop moeten
tikken...
Een laatste tooltje dat je nog zult nodig hebben om met PHP aan de slag te
kunnen, is XAMPP. Gezien PHP een server-side scripting taal is, moet de code
dus ook op een server uitgevoerd kunnen worden. XAMPP is een bundelpaket
dat Apache Web Server en MySQL bevat. Eens je dit geïnstalleerd en opgestart
hebt, kun je je PHP-documenten in je httpdoc folder plaatsen. Als je dan naar je
localhost surft, kun je het resultaat van je eerder geschreven code bekijken.
1.5 De Basis
Zoals hierboven reeds vermeld staat, is PHP een scripting taal die volledig
binnen HTML geïntegreerd kan worden. De vraag is natuurlijk hoe je dit precies
doet. Een blok PHP-code moet steeds beginnen met <?php en eindigen met ?>.
Je kunt ook met de korte notatie werken, die er als volgt uitziet: <? … ?>; maar
het wordt echter aangeraden om steeds de volledige notatie te gebruiken,
kwestie van zo min mogelijk problemen tegen te komen. Je kunt deze blok code
overal in de body van je HTML-document plaatsen. Het enige dat je dan nog
moet doen, is zorgen dat je je bestand opslaat met een .php extentie.
Op de volgende pagina vind je een voorbeeld van hoe PHP-code er zou kunnen
uitzien.
© feneX – Cursus PHP & MySQL p 4
<?php
//Drukt „Hello World‟ af op het scherm.
echo “Hello World!”;
?>
Het kleine stukje code hierboven zal Hello World op het scherm afdrukken, zoals
je ook al wel kon afleiden uit de commentaar die bij de code stond. In PHP zijn er
een aantal verschillende manieren om commentaar toe te voegen. Om één regel
commentaar toe te voegen, gebruik je twee forward slashes (//Commentaar) of
een hekje (#Commentaar). Je kunt echter ook een aantal regels commentaar
toevoegen, dit doe je door je commentaar tussen /* Commentaar */ te zetten.
Merk op dat er een puntkomma achter “Hello World” staat. Net als in de meeste
andere programmeertalen wordt ook in PHP elk statement afgesloten met een
puntkomma. In het volgende hoofdstuk zul je meer over de syntax en structuur
van PHP leren.
© feneX – Cursus PHP & MySQL p 5
Hoofdstuk 2
Syntax & Basisstructuren _________________________________________________________________ Cursus PHP & MySQL Groep D
© feneX – Cursus PHP & MySQL p 6
Hoofdstuk 2: Syntax & Basisstructuren
2.1 Types PHP is een relatief gemakkelijke taal om mee te werken, daar de syntax vrij
losjes is. Zo hoef je variabelen niet op voorhand te initialiseren. Je hoeft bij de
declaratie van je variabelen ook geen expliciet type op te geven. PHP kent de
variabele automatisch toe aan het juiste type. Als je een stuk tekst invoert, zal die
bijvoorbeeld automatisch opgeslagen worden als een string. Ook wanneer je
bewerkingen met variabelen doet, zal PHP de verschillende operanden
automatisch converteren naar het juiste type.
De verschillende types binnen PHP zijn integers, doubles, booleans, arrays,
NULL en objecttypes. We gaan ervan uit dat je de primaire types wel kent uit
andere programmeertalen, maar voor de volledigheid geven we toch nog snel
een kleine beschrijving mee. Zo zijn integers gewone gehele getallen, terwijl
doubles reële getallen zijn. Een boolean is een speciaal type dat enkel twee
waarden aanneemt: true of false. Dan zijn er nog arrays en objecttypes, waar we
later in de cursus op terugkomen. Ten slotte heb je nog NULL, wat een beetje
een vreemde eend in de bijt is. Het is een manier om je variabele geen waarde
mee te geven en leeg te laten.
Wanneer je met PHP werkt, zul je echter minder met types in contact komen dan
in andere talen, gezien de taal de typedeclaratie automatisch afhandelt.
2.2 Variabelen & Constanten We hebben het in de bovenstaande paragraaf al eventjes kort gehad over
variabelen. Wat we nog niet hebben aangehaald, is hoe we deze moeten
declareren. In PHP schrijft men steeds een dollarteken voor de identifier van een
variabele om duidelijk te maken dat we met een variabele te maken hebben. Een
variabele-declaratie zou er dus als volgt kunnen uitzien.
$var = 15;
De naam van een variabele mag enkel met een underscore of een letter
beginnen en mag verder slechts alfanumerieke karakters en underscores
bevatten. Wanneer variabelen niet expliciet geïnitialiseerd worden, worden ze op
de standaardwaarde geïnitialiseerd.
© feneX – Cursus PHP & MySQL p 7
Constanten binnen PHP krijgen geen dollarteken voor hun identifier en worden
met hoofdlettersgeschreven. (Bijvoorbeeld: E_ALL)
2.3 Operators
Merk op dat in het voorbeeld uit de vorige paragraaf de toekenning van de
variabele gebeurt aan de hand van het gelijkheidsteken en dus niet met
dubbelpunt is gelijk aan, zoals in Oberon of pseudo-code wel het geval is.
Naast de toekenning zijn er binnen PHP natuurlijk nog een boel andere
operators. Hieronder vind je een kleine samenvatting.
Toekennings-
operators
Beschrijving
= Toekenning
+= Telt de variabele rechts op bij de variabele links
-= Trekt de variabele rechts af van de variabele links
*= Vermenigvuldigt beide variabelen
/= Deelt variabele links door variabele rechts
%= Berekent de restdeling van de links en de rechtse variabele
.= Concatineert beide variabelen
Uit bovenstaande tabel kun je nu de wiskunde operanden vast wel afleiden. Het
plus- (+) en minteken (-) wordt uiteraard gebruikt voor de optelling en de
aftrekking. Het sterretje (*) voor de vermenigvuldiging, de forward slash (/) voor
de deling en het procentteken (%) voor de restdeling. Ook zijn er increment (++)
en decrement (--) operators voorzien binnen PHP die één optellen bij of aftrekken
van een bepaalde variabele.
Vergelijkende-
operators
Beschrijving
== Gelijkwaardig
=== Volledig identiek, ook wat type betreft
< Kleiner dan
> Groter dan
<= Kleiner of gelijk aan
>= Groter of gelijk aan
© feneX – Cursus PHP & MySQL p 8
Logische
operators
Beschrijving
! Niet
&& / and En
|| / or Of
2.4 Selectie- & Loopstructuren
2.4.1 Selectiestructuren
PHP kent dezelfde selectiestructuren die we ook in andere programmeertalen zijn
tegengekomen: de if else-structuur en de case-structuur. Die laatste heet in PHP
echter switch.
Allereerst zullen we de syntax van de if else structuur bekijken. Die ziet er als
volgt uit:
if (conditie)
{
statement;
}
else
{
statement;
}
De conditie schrijf je tussen haakjes, terwijl je de statements na de conditie
binnen accolades plaatst. Dit is enkel verplicht als je meer dan één statement
schrijft, maar voor de overzichtelijkheid schrijven we deze altijd. Merk op dat de
else-tak optioneel is en dat je een else if kunt maken door gewoon een extra if
toe te voegen binnen de else-tak.
De tweede en laatste selectiestructuur die je in PHP kunt gebruiken, is de
switch. Deze gebruik je vooral als je een bepaalde variabele wilt checken.
Naargelang de waarde van deze variabele ga je dan verschillende opdrachten
uitvoeren. We bekijken de syntax van de switch op de volgende pagina.
© feneX – Cursus PHP & MySQL p 9
switch (uitdrukking)
{
case waarde1:
statements;
break;
case waarde2:
statements;
break;
default:
statements;
break;
}
2.4.2 Lusstructuren
Ook wat iteraties betreft, kent PHP dezelfde structuren waar we al vertrouwd
meer geraakt zijn binnen andere programmeertalen en pseudo-code: de while, de
repeat until en de for-lus. In PHP heten die dan while, do while en for.
De eerste lus die we nader zullen bekijken, is de while. Hierbij controleer je eerst
of de conditie waar is, waarna je de statements binnen de body van de lus gaat
uitvoeren zolang de conditie waar blijft. De syntax ziet er als volgt uit:
while (conditie)
{
statements;
}
De twee iteratiestructuur is de do while, vergelijkbaar met de repeat until uit
Oberon of pseudo-code. Hierbij ga je de opdrachten binnen de lus minstens één
keer uitvoeren alvorens je de conditie gaat checken. Zolang de conditie waar is,
blijf je de opdrachten uitvoeren. De syntax vind je opnieuw hieronder:
do
{
statements;
}
while (conditie);
De derde loop die we gaan bespreken, is de for. Deze gebruik je wanneer je van
tevoren weet hoeveel keer je de lus wilt uitvoeren. De syntax hiervan vind je op
de volgende pagina.
© feneX – Cursus PHP & MySQL p 10
for (initialisatie lusvariabele, conditie, increment)
{
statements;
}
Hieronder vind je nog een voorbeeld om het iets duidelijker te maken.
for ($i = 1; $i<11; $i++)
{
//Druk de getallen van 1 tot 10 af.
print (i);
}
Naast de drie eerder besproken lussen bestaat er ook nog een for-each lus, waar
we later op terug zullen komen.
2.5 Invoer & Uitvoer
In PHP kun je uiteraard ook gegevens in- en uitlezen. Dat is natuurlijk enigszins
logisch gezien PHP zich hoofdzakelijk richt op het creëren van dynamische
webpagina‟s. We zullen in eerste instantie beginnen met de uitvoer. Hiervoor kun
je twee verschillende dingen gebruiken: ofwel het echo- of het print statement.
Als je je de vorige paragrafen nog herinnert, weet je vast nog wel dat we
hierboven reeds een voorbeeld van het echo statement gebruikt hebben. Je zou
op de volgende twee manieren „Hello World‟ kunnen laten afdrukken op het
scherm:
<?php
echo “Hello World”
?>
<?php
print (“Hello World”);
?>
Beide manieren zijn zo goed als volledig identiek aan elkaar. Het blijft dus eender
welke van de twee je gebruikt. Wij hebben echter steeds voor de print gekozen,
omdat deze ook nog teruggeeft of de print opdracht gelukt is of niet, wat later
tijdens complexere scripts misschien nog wel van pas kan komen.
© feneX – Cursus PHP & MySQL p 11
De invoer voor je PHP-scripts wordt aangeleverd door HTML en meer bepaald
door HTML-forms. Daarom dat het dus handig is dat je als PHP-scripter al een
beetje kaas van HTML gegeten hebt. Voor de volledigheid overlopen we de forms
hier wel nog even in de vlucht. Zulk een invoerformulier zou er bijvoorbeeld als
volgt kunnen uitzien:
<form action=”login.php” method=”post”>
Gebruikersnaam: <input type=”text” name=”user” />
Paswoord: <input type=”password” name=”password” />
<inpuyt type=”submit” name=”send” value=”Log in” />
</form>
In bovenstaand voorbeeld zou je al heel wat dingen moeten opmerken: allereerst
de form-tag met zijn attributen action en method, alsook de verschillende input-
tags. Met het action attribuut vertel je waar de waarden uit de form naartoe
moeten. Meestal zal dit dezelfde pagina zijn. In onze voorbeelden hebben wij
vaak van het volgende gebruik gemaakt:
<form action=”<?php print ($_SERVER['PHP_SELF']); ?>”>
Hier doen we iets speciaals, we gebruiken namelijk een globale variabele die
ervoor zorgt dat we actie niet telkens moeten aanpassen wanneer de naam van
de pagina verandert. Het zal de huidige url kopiëren en in het action-attribuut
plaatsen. Soms kun je hier problemen mee hebben, wanneer je met GET-
variabelen werkt. Meer over GET en POST variabelen lees je hieronder.
Binnen diezelfde form-tag vinden we ook het method-attribuut. Hiermee bepalen
we hoe we onze invoer willen verzenden. Er zijn twee mogelijkheden.
De eerste optie is het gebruiken van de $_GET variabele. Deze variabele wordt
gebruikt om aan de hand van de get-methode de waarden uit een form op te
halen. De variabele op zich is een array van waarden. Let wel op dat de waarden
die op deze manier opgehaald worden voor iedereen zichtbaar zijn, daar ze in de
adresbalk van de gebruiker weergegeven worden. Het zou er dus als volgt
kunnen uitzien in je adresbalk:
http://www.voorbeeldsite.be/index.php?naam=joris&richting=1TI
Wanneer je de get-methode gebruikt, zijn de waarden dus zichtbaar voor
iedereen. Het spreekt voor zich dat we deze dus beter niet gebruiken bij het
verzenden van paswoorden of andere gevoelige informatie. Bovendien kun je
© feneX – Cursus PHP & MySQL p 12
maximaal honderd karakters gebruiken, wat de methode een beetje beperkt
maakt.
Een andere mogelijkheid is het gebruik van de $_POST variabele. Deze haalt de
waarden uit de form op aan de hand van de post-methode en stopt deze in een
array. Het voordeel hier is dat de waarden niet zichtbaar zijn naar de
buitenwereld toe en dat er geen limiet op het aantal karakters staat. Deze manier
is dus veiliger dan de voorgaande.
Waarden die je op één van deze twee manieren hebt opgehaald, kun je dan als
volgt gaan gebruiken in je code.
<?php
print (“Naam: ” . $_POST[„naam‟]);
?>
Het laatste wat je gezien hebt, bij het gebruik van de forms, zijn de html-tags die
je gebruikt om invoer in op te geven. De belangrijkste zijn <input>, <textarea> en
<select>.
Bij de input-tag heb je de volgende mogelijke attributen die je kunt gebruiken,
samen met hun verschillende mogelijke waardes.
type
text: Een veld waar je gewoon tekst in kunt ingeven;
password: Paswoord veld dat **** toont i.p.v. de eigenlijke tekst;
submit: Stuurt de form door naar de actionpagina;
reset: Leegt alle velden;
radiobutton: Slechts één optie te selecteren (ronde bolletjes);
checkbox: Meerdere opties te selecteren (vierkantjes met
vinkjes);
hidden: Wordt niet op het scherm getoond, maar wel
meegegeven.
name
Unieke identifier die je zelf kunt kiezen.
value
Wat er in het veld komt te staan of standaard wordt
weergegeven.
Textarea is multiline tekstvak waarin je logischerwijs heel wat tekst kunt
schrijven, hierbij moet je drie verplichte attributen opgeven.
© feneX – Cursus PHP & MySQL p 13
cols
Het aantal kolommen/karakters die je naast elkaar kunt plaatsen.
rows
Het aantal rijen onder elkaar.
Name
Unieke identifier die je zelf kunt kiezen.
De select-tag stelt ons dan weer in staat om een dropdown-box te creëren.
Binnen deze tag hebben we dan de extra tag option nodig. Dit zou er dan als
volgt uitzien.
<select name=”jaar”>
<option value=”1TI”>1TI</option>
<option value=”2TI”>2TI</option>
<option value=”3TI”>3TI</option>
</select>
2.6 Beveiliging Als je invoer van formulieren krijgt, moet je die natuurlijk ook ergens kunnen
valideren en kijken of je wel zinnige invoer toegestuurd krijgt. Een gebruiker kan
namelijk verkeerde invoer ingeven die wij als webmaster niet verwachten. Zo zou
de gebruiker in het vak leeftijd bijvoorbeeld de letter „a‟ kunnen invoeren, terwijl
wij natuurlijk een getal verwachten. Je kunt dit met client-side validatie oplossen
door javascript te gaan gebruiken, maar je kunt het even goed aan de kant van
de server oplossen door met PHP te werken. Zeker als je met een database
werkt, is het veiliger om het valideren aan de kant van de server te doen. Een
manier om goed te valideren, is om het formulier op dezelfde pagina te posten,
zo krijgt de gebruiker de foutmeldingen nog op dezelfde pagina waar het
formulier staat.
Om de invoer te controlleren, zijn er in PHP een heleboel handige methodes
voorzien, waarvan we er hieronder enkele bondig zullen bespreken. Er zijn er
natuurlijk nog heel wat meer dan degene die wij hier opgeven, maar dit zijn de
meest courante. Voor alle andere mogelijkheden verwijzen we je graag door naar
php.net.
© feneX – Cursus PHP & MySQL p 14
isset($var);
De eerste methode die we nader bekijken; hiermee kunnen we zien of er al dan
niet op een button is geklikt. Als je dit evalueert met een if-structuur kun je naar
gelang of er wel of niet op een button geklikt is de ene of de andere actie
uitvoeren.
empty($var);
Deze methode wordt dan weer gebruikt om te kijken of een veld leeg is of niet.
Let echter wel op met het cijfer nul. Wanneer er nul werd ingegeven, zal dit ook
bekeken worden als zijnde een leeg veld. Om met cijfers te werken, zijn er
andere methodes die handiger zijn, zoals onderstaande.
is_numeric($var);
Hierbij gaan we kijken of de ingegeven waarde een getal is of niet.
Zoals we eerder al aanhaalden, zijn er uiteraard nog tal van andere methodes die
je kunt gebruiken, maar daarvoor verwijzen we je graag door naar de volledige
php handleiding die je op php.net vindt.
© feneX – Cursus PHP & MySQL p 15
Hoofdstuk 3
Arrays & Containers _________________________________________________________________ Cursus PHP & MySQL Groep D
© feneX – Cursus PHP & MySQL p 16
Hoofdstuk 3: Arrays & Containers
3.1 Wat zijn Arrays? Arrays zijn een speciale soort variabelen die een serie waardes kunnen opslaan.
Een array bestaat uit een lijst met waarden en indexen. Het voordeel hiervan is
dat je meerdere zaken makkelijk bij elkaar kunt plaatsen in één en dezelfde
variabele. Elke waarde binnen een array heeft zijn eigen unieke index waarmee
je ze kunt aanspreken. Hieronder vind je een voorbeeld van een numerieke array.
<?php
$namen = array(“Jeroen”, “Martijn”, “Joris”, “Nick”);
?>
Een numerieke array geeft aan elke waarde van de array een unieke, numerieke
index. In bovenstaand voorbeeld gebeurt dit automatisch. In onderstaand
voorbeeld gaan we de index handmatig toekennen. Let op, de index van een
array begint steeds vanaf nul en niet bij één.
<?php
$namen[0] = “Pieter-Jan”;
$namen[1] = “Bart”;
?>
We zouden een array ook op onderstaande manier kunnen declareren.
<?php
$array = array(1, 1, 1, 1, 1, 8 => 1, 4 => 1, 19, 3 => 13);
print_r($array):
?>
Wanneer we deze array uitprinten met behulp van de print_r methode – die een
leesbare versie van de array helemaal uitprint, krijgen we het volgende te zien.
© feneX – Cursus PHP & MySQL p 17
Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 13
[4] => 1
[8] => 1
[9] => 19
)
Merk op dat we index 3 van de array tweemaal hebben toegekend. Deze index
zal de waarde 13 bevatten, omdat deze als laatste in index 3 werd geplaatst. Ook
zien we dat index 4 na index 8 wordt gedefinieerd, de waarde 19 komt op index 9
omdat 8 de grootste index was.
Naast numerieke arrays bestaan er nog twee andere soorten arrays, met name
associatieve en meerdimensionale arrays. Bij associatieve arrays associëren we
de waardes van de array met een speciale key/index. Hieronder vind je een
voorbeeld van een associatieve array.
<?php
$geboortejaar = array(“Maarten” => 1990, “Joris” => 1988)
?>
Een meerdimensionale array is een array die als waarden ook andere arrays
accepteert. Zo zou je binnen de array TI, drie arrays kunnen stoppen: 1TI, 2TI en
3TI, die elk alle studenten uit dat jaar bevatten. We gaan hier echter geen
voorbeeld van uitschrijven. We gaan ervan uit dat je dit ondertussen ook zo wel
begrijpt.
3.2 Loopen over Arrays Om een array uit te lezen, maakt men gebruik van een lusstructuur. Je zou dit
met een while- of een for-lus kunnen doen, maar speciaal voor arrays bestaat er
nog een ander type lus die je kunt gebruiken, met name de for each.
De for each loopt over de hele array en toont zo bijvoorbeeld alle waarden in de
lijst. Elke waarde in de array wordt toegekend aan de variabele $value, de index
wordt telkens je terug aan de lus begint opgehoogt, totdat je heel de array
uitgelezen hebt.
© feneX – Cursus PHP & MySQL p 18
De syntax van de for each ziet er als volgt uit.
<?php
foreach ($array as $value)
{
statements;
}
?>
Hieronder staat een klein voorbeeld van het gebruik van de for each lus.
<?php
$soortenArrays = array(“Numerieke”, “Associatieve”,
“Meerdimensionale”)
print (“Soorten arrays: “);
foreach ($soortenArrays as $key => $value)
{
print ($key . $value);
}
?>
Merk op dat je de index ook kunt gebruiken binnen de for each, dit is echter niet
verplicht.
3.3 Functies PHP kent een heleboel functies om met arrays te werken. In deze paragraaf
zullen we enkele van de meest gebruikte functies op arrays kort bespreken. Zo
behandelen we de fill-, de count-, de recursive count-, de count values-, de sort-,
de merge-, de implode- en de explode functie.
Array Fill Functie
In dit voorbeeld zeggen we dat we bij index 5 willen beginnen en dat we 6 maal
het woord „php‟ in onze array gaan plaatsen.
<?php
$a = array_fill(5, 6, 'php');
print_r($a);
?>
De uitvoer van dit stukje code zou er dan als volgt uitzien:
© feneX – Cursus PHP & MySQL p 19
Array
(
[5] => php
[6] => php
[7] => php
[8] => php
[9] => php
[10] => php
)
Count Functie
De count functie berkent het aantal waarden binnen de array. Als je drie waarden
binnen je aray hebt staan, zal de count functie dus drie retourneren.
<?php
$a[0] = 1;
$a[1] = 3;
$a[2] = 5;
$result = count($a);
?>
De variabele $result zal de waarde 3.
Recursive Count Functie
De recursive count telt alle waarden die in de array voorkomen, dus ook arrays in
arrays. De gewone count functie telt enkel de waarden van de eerste array die hij
tegenkomt.
<?php
$eten = array('fruit' => array('peer', 'banaan', 'appel'),
'groeten' => array('wortel', 'witloof', 'spinazie'));
print (count($eten, COUNT_RECURSIVE);
?>
Count Values Functie
In dit voorbeeld gaan we na hoeveel maal er een bepaalde waarde in een array
voorkomt.
<?php
$array = array(1, "php", 1, "TI", "php");
print_r(array_count_values($array));
?>
© feneX – Cursus PHP & MySQL p 20
De uitvoer zou er dan als volgt uitzien:
Array
(
[1] => 2
[php] => 2
[TI] => 1
)
Sorteren van een Array
In dit voorbeeld gebruiken we een for each om de waarden van de array
alfabetisch te sorteren.
<?php
$fruit = array("limoen", "peer", "banaan", "appel");
sort($fruit);
foreach ($fruit as $key => $val)
{
echo "fruit[" . $key . "] = " . $val . "\n";
}
?>
Output ziet er als volgt uit:
fruit[0] = appel
fruit[1] = banaan
fruit[2] = limoen
fruit[3] = peer
Merge 2 Arrays
In dit voorbeeld gaan we array1 en array2 samenvoegen.
<?php
$array1 = array("kleur" => "rood", 2, 4);
$array2 = array("a", "b", "kleur" => "groen", "vorm" => "trap
ezium", 4);
$result = array_merge($array1, $array2);
print_r($result);
?>
© feneX – Cursus PHP & MySQL p 21
Output ziet er als volgt uit:
Array
(
[kleur] => groen
[0] => 2
[1] => 4
[2] => a
[3] => b
[vorm] => trapezium
[4] => 4
)
Merk op dat de waarde „rood‟ is verdwenen bij het samenvoegen van de arrays,
dit komt omdat array2 ook een index „kleur‟ heeft met de waarde „groen‟. Deze
overschrijft de index color van array1 met de waarde „groen‟.
Implode
Met de implode functie is het mogelijk om een extra teken mee af te drukken na
elke waarde van array. In dit voorbeeld gaan we tussen elke waarde een komma
plaatsen.
<?php
$array = array('naam', 'e-mail', 'tel');
$comma_separated = implode(",", $array);
echo $comma_separated; // naam,e-mail,tel
?>
Explode
Met deze functie kunnen we een string opsplitsen na een teken dat men zelf
bepaalt.
<?php
$pizza = "stuk1 Stuk2 stuk3 stuk4 stuk5 stuk6";
$stukken = explode(" ", $pizza);
echo $stukken[0]; // stuk1
echo $stukken[1]; // stuk2
?>
In dit voorbeeld gaan we na elke “ “ (witruimte) de string „$pizza‟ splitsen en deze
afdrukken.
© feneX – Cursus PHP & MySQL p 22
3.4 Strings Zoals je ondertussen al wel weet, is een string een variabele die een stukje tekst
kan opslaan. Zoals in elke andere programmeertaal moet de tekst die je aan je
string variabele wilt toekennen tussen dubbele quotes staan.
Je kunt een heleboel functies toepassen op strings. In dit hoofdstuk bekijken we
de drie meest gebruikte en geven we een klein voorbeeldje van het gebruik
ervan.
Een eerste functie die je kunt gebruiken, is string length (strlen), deze wordt
gebruikt om de lengte van een bepaalde string te bepalen. Onderstaande code
zou dus „12‟ als uitvoer moeten hebben.
<?php
strlen(“Hello World”);
?>
Een tweede functie die veelvuldig gebruikt wordt, is strpos functie, deze wordt
gebruikt om te bepalen of een bepaald karakter of woord zich in een string
bevindt. De functie geeft dan de index terug waarop het woord gevonden werd.
Indien er niks gevonden wordt, retourneert de methode FALSE. In onderstaande
voorbeeld vind je World terug op index 6. Je krijgt zes en niet zeven, omdat de
index begint vanaf nul.
<?php
echo strpos(“Hello World”, “World”);
?>
Een laatste veelgebruikte functie is de substring functie. Deze functie
retourneert een deel van een specifieke string te beginnen vanaf een bepaalde
index en van een bepaalde lengte. De lengte-parameter is echter optioneel. De
syntax hiervan ziet er dus als volgt uit.
<php
substr(string, start, length);
?>
Er zijn nog een aantal andere functies zoals strtolower, strtoupper en Str_replace.
Eerstgenoemde zet de string om naar een string van allemaal kleine letters,
terwijl de tweede je string omvormt naar ééntje met allemaal hoofdletters. De
laatste methode ontvangt drie parameters: een substring die je wil vervangen, de
© feneX – Cursus PHP & MySQL p 23
substring waarmee je de vorige wil mee vervangen, en de string waarin je dit
moet doen.
Hieronder vind je een voorbeeldje van wat je bijvoorbeeld zou kunnen doen met
deze methodes. In dit voorbeeld wordt een string ingegeven en wordt die
achterstevoren op het scherm afgedrukt.
<form action="switcharoo.php" method="post"> Naam: <input type="text" name="vervang" /><br /> <input type="submit" name=” submit” value=”Submit” /> </form> <?php if(isset($_POST['naam'])) { $naam = $_POST['naam']; $lengteVanNaam = strlen($naam); for($i=0; $i<=$lengteVanNaam; $i++) { echo substr($naam,$lengteVanNaam-$i,1); } } ?>
(Met dank aan onze klasgenoot Yenthe Oerlemans!)
Nog een laatste dingetje dat we kwijt willen nu we het toch over strings hebben, is
het feit dat je binnen strings met escape sequences kunt werken. Dit om
bijvoorbeeld een dubbele quote binnen een string af te drukken. Als je dit zonder
escape sequences zou proberen, gaat hij die quote opnemen als het einde van
de string in plaats van hem af te drukken. Gelukkig is er een manier om dit te
omzeilen, met name het gebruik van escape sequences. Om een
aanhalingsteken af te drukken zet je \” in je string. De backslash wordt
genegeerd, terwijl de dubbele quote gewoon afgedrukt zal worden.
Zo zijn er nog een aantal, met name:
\”: drukt dubbele quotes af;
\‟: drukt een enkele quote af;
\n: gaat verder op een nieuwe regel
\t: voegt een tab toe
\$: print het dollarteken, neem het niet op als het begin van een
variabele
\\: print een backslash, neem het niet op als het begin van een escape
sequence
© feneX – Cursus PHP & MySQL p 24
Hoofdstuk 4
Functies & Klasses _________________________________________________________________ Cursus PHP & MySQL Groep D
© feneX – Cursus PHP & MySQL p 25
Hoofdstuk 4: Functies & Klasses
4.1 Functies Definiëren Functies kunnen heel handig zijn, zeker bij een grote website om de website
ordelijk en netjes te houden en om ervoor te zorgen dat je handelingen die je
vaker moet verrichten – bijvoorbeeld een bepaalde query – maar één keer hoeft
te schrijven, en je deze vervolgens overal kunt benaderen.
Er bestaan drie verschillende soorten functies binnen PHP: je kunt functies
volledig zelf schrijven, daar gaan we iets dieper op in in deze paragraaf; je kunt
voorgedefinieerde functies binnen PHP gebruiken, hierover meer in de volgende
paragraaf; of je kunt externe bibliotheken gebruiken zoals mysql_connect.
Hieronder vertellen we je hoe je binnen PHP een functie moet definiëren. We
beginnen voor de gemakkelijkheid met een functie zonder parameters of return
values. Deze voorbeeldfunctie zal een foutmelding op het scherm printen
wanneer ze wordt aangeroepen.
<?php
function errorMessage()
{
print (“Het ingevoerde paswoord is incorrect!”);
}
errorMessage(); //Hier wordt de functie aangeroepen
?>
Zoals je in het bovenstaande voorbeeld gezien hebt, begin je een functie steeds
met het woord function, vervolgens geef je ze een logische naam, die duidelijk
maakt wat de functie gaat doen. Binnen de accolades voeg je dan de body van je
functie toe.
We kunnen het ook iets complexer maken door parameters aan onze functies toe
te voegen. Je kunt namelijk gegevens aan functies doorgeven door middel van
een parameterlijst. Parameters zet je, gescheiden door een komma, tussen de
ronde haken die volgen na de naam van je functie. Als je functie ook nog een
waarde moet teruggeven, werk je met returnvalues. Je zou iedere keer je
waardes kunnen echo‟en, maar dat werkt niet zo handig. Onthoud ook dat
variabelen die binnen functies gedeclareerd worden lokaal zijn en dus niet meer
bestaan buiten je functie. Vandaar dat we return values gebruiken.
© feneX – Cursus PHP & MySQL p 26
Hieronder vind je een simpel voorbeeld van een functie met twee parameters en
een return statement. Ze telt de twee ingegeven parameters bij elkaar op en
retourneert de som.
<?php
function optellen($getal1, $getal2)
{
$som = $getal1 + $getal2;
return $total;
}
print (optellen(5, 11)); //Hier wordt de functie aangeroepen
?>
4.2 Functies binnen PHP Eén van de voordelen van PHP is dat het reeds beschikt over een groot aantal
voorgedefinieerde functies die je naar eigen goeddunken kunt gaan gebruiken.
Je hoeft het warm water dus niet opnieuw uit te gaan vinden. Als je een probleem
moet oplossen, is het handig om eens even te kijken of er al geen functie bestaat
die iets gelijkaardig doet als datgene dat jij wil gaan implementeren.
Zo hebben we de Date functie bijvoorbeeld gebruikt in één van onze oefeningen.
Zie hoofdstuk 7. Het leidt ons te ver om de documentatie van deze functies in de
cursus op te nemen. Hiervoor verwijzen we je opnieuw door naar php.net, waar je
alle informatie over de voorgedefinieerde functies binnen PHP kunt terugvinden.
4.3 Klasses Definiëren Daar PHP ook een object georiënteerde programmeertaal is, werkt het dus ook
met objecten en klasses. De manier waarop je klasses definieert en gebruikt is
vergelijkbaar met die van Java. Voor de volledigheid gaan we hier echter ook
eventjes dieper ingaan op het definiëren van een eigen klasse. Voor een volledig
naslagwerk over het schrijven van klasses binnen PHP verwijzen we je opnieuw
door naar de officiële PHP-handleiding.
Wat is nu precies een klasse? Een klasse bevat definities die een soort bouwplan
vormen voor het maken van objecten. Het voordeel van het maken van een
klasse is dat je meerde instanties van die klasse kunt maken en bijgevolg
efficiënter en eenvoudiger code kunt schrijven.
© feneX – Cursus PHP & MySQL p 27
De syntax van een klasse ziet er als volgt uit. Ze begint steeds met het woordje
class, gevolgd door de identifier. Aan de hand van die identifier kun je de
methodes van de klasse aanroepen en gebruiken.
<?php
class MyClass
{
body;
}
?>
Binnen een klasse worden verschillende variabelen gedeclareerd voor gebruik
binnen de klasse. Deze kunnen (vanaf PHP5) gedefinieerd worden als zijnde
private of public. Private variabelen kunnen enkel binnen de klasse benaderd
worden, terwijl public variabelen van overal aanroepbaar zijn. Dit laatste dient
zoveel mogelijk vermeden te worden, gezien de variabele dan te gemakkelijk aan
te passen is en dit voor ongewenste resultaten kan zorgen. Gebruik indien
mogelijk steeds private variabelen.
Binnen een klasse kun je vervolgens een heleboel functies gaan definiëren. We
hebben in de vorige paragrafen gezien hoe dit in zijn werk gaat. Hieronder vind je
een voorbeeld van hoe een klasse er tot op heden zou kunnen uitzien.
<?php
class MyClass
{
private $var1;
public function geefWaarde($var)
{
$this->var1 = $var;
}
}
?>
Bij het aanroepen van de functie „geefWaarde” zal de waarde van de ingegeven
parameter doorgegeven worden aan de variabele uit de klasse. Het $this
keyword wordt gebruikt om naar de klasse te verwijzen. Het aanroepen van een
functie of variabele binnen de klasse doe je door het keyword $this te gebruiken,
gevolgd door een pijltje (->), daarna plaats je de functie of variabele die je wenst
te gebruiken.
© feneX – Cursus PHP & MySQL p 28
We hebben zonet het gebruik van het pijltje en $this gezien. Dit om variabelen en
functies binnen eenzelfde klasse aan te roepen. Indien je functies uit een andere
klasse wilt aanroepen gebruik je twee dubbele punten (::), zoals beschreven in
onderstaand voorbeeld.
<?php
class A
{
function voorbeeldFunctie ()
{
echo “Voorbeeld”;
}
}
class B
{
function voorbeeld()
{
A::voorbeeldFunctie();
}
}
$a = new A();
$a->voorbeeldFunctie();
$b = new B();
$b->voorbeeld();
B::voorbeeldFunctie();
?>
In bovenstaand voorbeeld hebben we meteen ook gezien hoe we een nieuwe
instantie van een klasse maken. Dit doen we dus als volgt.
<?php
$instantie = new KlasseNaam();
?>
Soms is het handig om bij het instantiëren van een object meteen een aantal
statements uit te voeren. Dit kunnen we verwezenlijken door gebruik te maken
van een constructor, zoals we dat ook kennen uit Java. Die kunnen we creëren
door een functie met de naam __construct (dubbele underscore) toe te voegen
of door een functie toe te voegen die dezelfde naam als de klasse heeft.
© feneX – Cursus PHP & MySQL p 29
4.4 Cookies & Sessions
4.4.1 Cookies
Cookies worden vaak gebruikt om een gebruiker te identificieren. Een cookie is
een klein bestandje dat de server achterlaat op de PC van de gebruiker. Telkens
de gebruiker een pagina opvraagt, zal hij ook deze cookie meesturen.
Om een cookie aan te maken, gebruiken we de setcookie methode. Let wel,
deze methode dien je vóór de html-tags van je pagina te schrijven! Hieronder
vind je de syntax van deze methode. We hebben een cookie „Naam‟ gecreëerd
die als waarde value heeft en die over één dag zal vervallen.
<?php
setcookie(“Naam”, “Value”, time() + (24*60*60));
?>
Om de waarde van een cookie te kunnen lezen, wordt de $_COOKIE variabele
gebruikt. Dit is een voorgedefinieerde array variabele. We zouden zo bijvoorbeeld
de waarde van bovenstaande cookie kunnen afdrukken:
<?php
echo $_COOKIE[„Naam‟];
?>
Om een cookie te verwijderen, zorgen we ervoor dat de vervaldatum zich in het
verleden bevindt.
4.4.2 Sessions
Sessions worden gebruikt om informatie op te slagen of om de instellingen van
een user session aan te passen. Deze variabelen bevatten informatie over één
enkele gebruiker en zijn beschikbaar over heel je webapplicatie.
Aan de hand van sessions kun je nagaan hoeveel views je hebt of zien wanneer
een gebruiker online is en dergelijke. Elke bezoeker krijgt een unieke ID
toegekend, die gebruikt wordt om alle informatie op te slaan.
Om waarden aan sessions toe te kennen, moeten we natuurlijk eerst een sessie
starten. Dit doe je als volgt.
<?php
sessions_start();
?>
© feneX – Cursus PHP & MySQL p 30
Merk op dat dit stukje code vóór de html-tag moet staan! Om waarden aan een
session toe te kennen gebruiken we de speciale $_SESSION variabele. In
onderstaand voorbeeld hebben we een simpele pageview teller
geïmplementeerd.
<?php
session_start();
if(isset($_SESSION['views']))
{
$_SESSION['views']=$_SESSION['views']+1;
}
else
{
$_SESSION['views']=1;
}
echo "Views:". $_SESSION['views'];
?>
Om een session te verwijderen, gebruiken we de unset- of de session_destroy
methode. Aan de hand van de unset functie kunnen we een bepaalde waarde
van de session verwijderen; met session_destroy verwijderen we de session
volledig. Hieronder vind je de syntax van beide methodes.
<?php
unset($_SESSION[„views‟]);
session_destroy();
?>
4.5 Include & Require
Server Side Includes worden gebruikt om functies, headers, footers of andere
elementen te creëren die op meerdere pagina‟s gebruikt zullen worden. Dit kan je
heel wat tijd besparen, wanneer je bijvoorbeeld eenzelfde header op elke pagina
hebt, of een navigatiemenu. Je hoeft het dan enkel in je header.php bestand aan
te passen wanneer het verandert, in plaats van op elke afzonderlijke pagina. De
syntax voor include en require ziet er als volgt uit.
<?php
include (“header.php”);
require (“header.php”);
?>
© feneX – Cursus PHP & MySQL p 31
Beide methodes doen exact hetzelfde. Het verschil ligt hem in de manier waarop
ze met foutmeldingen omgaan. Hier zullen we echter niet dieper op ingaan in
onze cursus.
© feneX – Cursus PHP & MySQL p 32
Hoofdstuk 5
MySQL Integratie _________________________________________________________________ Cursus PHP & MySQL Groep D
© feneX – Cursus PHP & MySQL p 33
E Hoofdstuk 5: MySQL Integratie
5.1 Werken met MySQL MySQL is een databank zoals SQL voor Linux/Unix servers. Deze zijn zeer
compact en bieden meerdere voordelen voor webapplicaties. Zo kun je
bijvoorbeeld een log-in maken. Hiervoor moet je dan nog wel weten hoe je een
database kun aanmaken. Daar vertellen we je dan weer alles over in dit
hoofdstuk. Een database bestaat uit verschillende tabellen en tabellen bestaan
op hun beurt uit verschillende records (rijen) en kolommen.
Wij werken voor dit deel met PHPMyAdmin. Dit is een applicatie voor het internet,
waar je eenvoudig databanken en tabellen in kunt maken met nog extra functies.
Er zijn ook nog andere applicaties, maar deze gaan we niet bespreken.
Hoe maken we nu een database in MySQL?
In bovenstaande afbeelding werder er twee vakjes omlijnd met een oranje kader.
Deze zijn nodig om een database aan te maken. In het eerste vakje schrijf je de
naam van je database. Het tweede type geeft aan van welk type ze moet zijn. Dit
wordt meestal door de webserver ingesteld op utf8_general_ci.
Als we onze database gecreëerd hebben, moeten we vervolgens een aantal
tabellen aanmaken. Dit wordt uitgelegd aan de hand van de volgende afbeelding.
© feneX – Cursus PHP & MySQL p 34
Ook hier zie je weer twee vakjes die in het oranje staan. In het eerste veld voeren
we de naam van onze tabel in en in het tweede veld zetten we hoeveel velden
we gaan maken in onze tabel.
Vervolgens krijg je dit te zien. Hier kun je al je velden benoemen en er een type
aan toewijzen. Er zijn een aantal verschillende soorten types, waar we hieronder
nader op ingaan.
Char – Varchar
Altijd evenveel tekens: CHAR (codes enz.)
Niet altijd volledig gevuld: VARCHAR (trager, neemt minder plaats in)
Gebruik OPTIMIZE TABLE om de varchars te defragmenteren.
© feneX – Cursus PHP & MySQL p 35
Text – BLOB
Gebruik in deze tabel geen SELECT * FROM, maar benoem de velden.
Signed – Unsigned
Negatieve getallen in gebruik: SIGNED. Bereik gaat van een minimale,
negatieve waarde tot een maximale positieve waarde.
Geen negatieve: UNSIGNED. Bereik ligt volledig langs de positieve kant.
Primary Key
De primaire sleutel van de tabel.
Auto-increment
Start vanaf 0? Gebruik UNSIGNED (dubbel zoveel waarden mogelijk)
Ga steeds na hoeveel records je nodig hebt en gebruik een zo klein mogelijk
datatype!
0-255: UNSIGNED TINYINT
0-65.000 UNSIGNED SMALLINT
0-16.000.000: UNSIGNED MEDIUMINT
>4 miljard: UNSIGNED INT
Overzicht:
Type Bytes Minimum Value Maximum Value
(Signed/Unsigned) (Signed/Unsigned)
TINYINT 1 -128 127
0 255
SMALLINT 2 -32.768 32.767
0 65.535
MEDIUMINT 3 -8.388.608 8.388.607
0 16.777.215
INT 4 -2.147.483.648 2.147.483.647
0 4.294.967.295
BIGINT 8 -9.223.372.036.854.775.808 9.223.372.036.854.775.807
0 18.446.744.073.709.551.615
© feneX – Cursus PHP & MySQL p 36
5.2 De SELECT Functie Nu we een database en een tabel gemaakt hebben, willen we natuurlijk graag de
waardes uit onze tabel kunnen halen. Dit gaat vrij simpel. We doen dit namelijk
aan de hand van een select query. We zullen de syntax van onderstaande
SELECT query even nader bekijken.
SELECT * FROM TabelNaam WHERE VeldNaam = „ ‟ AND/OR
VeldNaam = „ ‟ ORDER BY VeldNaam ASC, DESC;
U ziet hier SELECT * FROM TabelNaam. Dit is het belangrijkste deel van heel de
SELECT. Op de plaats van het sterretje kun je elk veld uit de tabel „TabelNaam‟
zetten. Als je alles wilt ophalen, kun je dit doen aan de hand van het sterretje. Op
de plaats van TabelNaam moet je natuurlijk de naam van de tabel zetten waaruit
je alles wilt gaan selecteren.
Vervolgens zie je ook WHERE staan, waar je een conditie, bijvoorbeeld
veldnaam = „aap‟, kunt plaatsen waar de select aan moet voldoen vooraleer er
iets wordt teruggegeven.
De ORDER BY is de manier waarop de select de waardes gaat terug geven, met
name in welke volgorde. DESC (descending) wijst op omgekeerde volgorde,
terwijl ASC (ascending) oplopend wil zeggen.
5.3 De INSERT Functie Naast iets uit de databases te selecteren, kunnen we natuurlijk ook iets gaan
toevoegen. Ook dit is eigenlijk vrij eenvoudig. We doen dit aan de hand van de
INSERT query, die hieronder nader bekeken wordt.
INSERT INTO TabelNaam (VeldNaam_1, VeldNaam_2) VALUES
(„Waarde_1‟, „Waarde_2‟);
We schrijven eerst en vooral INSERT INTO en vervolgens de naam van onze
tabel waar we iets aan willen toevoegen. Daarna openen we de haakjes. Tussen
de haakjes zetten we onze velden. Deze moeten natuurlijk overeen komen met
de velden uit de tabel, maar mogen wel in willekeurige volgorde staan. Ten slotte
schrijven we VALUES en schrijven we onze gegevens daarna tussen haakjes. Dit
doen we als volgt: VALUES („Waarde_1‟, „Waarde_2‟); vergeet niet in welke
volgorde je de veldnamen hebt gezet, want zo moet je natuurlijk ook je values
zetten.
© feneX – Cursus PHP & MySQL p 37
5.4 De UPDATE Functie Heb je een foutje gemaakt bij je INSERT? Geen enkel probleem, om dit recht te
zetten, gaan we een UPDATE statement toepassen. Hieronder vind je de syntax
van deze MySQL-query die we dadelijk nader gaan bekijken.
UPDATE TabelNaam SET VeldNaam_1 = „Waarde_1‟, VeldNaam_2
= „Waarde_2‟ WHERE VeldNaam_3 = „Waarde_3‟;
De UPDATE wordt eerst gevolgd door onze tabelnaam. Daarna zetten we een
SET die gaat bepalen welke velden worden aangepast door welke value. Als je
meerdere velden wilt wijzigen, moet je telkens een scheidingsteken zetten tussen
de velden. Hiervoor gebruiken we een komma. Achter de SET met velden gaan
we een WHERE plaatsen. Deze zal ervoor zorgen dat niet alles geüpdatet wordt,
maar enkel de vooraf bepaalde regels.
5.5 De DELETE Functie Dit is vrij duidelijk. Een regel verwijderen uit een bepaalde tabel met een
bepaalde waarde waar aan voldaan moet worden. Hieronder vind je opnieuw de
syntax, vervolgens komen we er weer even kort op terug.
DELETE FROM TabelNaam WHERE VeldNaam_1 = „Waarde_1‟;
Eerst starten we met een DELETE FROM en onze tabel waar we willen uit
verwijderen. Vervolgens zetten we een WHERE met een veld en een bepaalde
waarde. Dit veld zal dan uiteindelijk uit onze database worden verwijderd.
5.5 Integratie met PHP Nu we alles bijna kennen, van onze select tot delete, gaan we verder met een
beetje informatie over hoe we een database aanroepen via PHP en hoe we een
tabel in die database kunnen gebruiken. Vergeet niet dat wanneer je je PHP- en
MySQL server lokaal draait er een paar zaken anders zullen zijn.
Met onderstaande code gaan we een database aanroepen.
$iConnect = mysql_connect (HOST, GEBRUIKERSNAAM,
PASWOORD);
© feneX – Cursus PHP & MySQL p 38
In de variabele $iConnect zetten we onze mysql_connect(). Die gaat een waarde
teruggeven die we later nodig zullen hebben. De mysql_connect functie heeft drie
parameters. Ten eerste de host naar waar je wilt gaan. 99% van de tijd is dit
gewoon localhost; de tweede parameter is de gebruikersnaam. Deze krijg je
meestal van je hosting bedrijf mee. Als je lokaal test is dit ROOT. De laatste
parameter is het paswoord dat je ook meekrijgt van de server. Als je lokaal werkt,
mag je dit weglaten.
Dit gebruik je dus wanneer je lokaal werkt:
$iConnect = mysql_connect („localhost‟, „root‟);
Het volgende stukje code gaat de database aanroepen:
mysql_select_db (DATABASE, $iConnect);
Ook hier komt $iConnect terug. Natuurlijk ga je op de plaats van DATABASE de
naam van je database zetten.
Na de connectie te hebben gemaakt, gaan we even kijken hoe je zelf geschreven
queries kunt uitvoeren. Dit doen we aan de hand van de volgende code.
$iResult = mysql_query (QUERYSTRING, $iConnect);
Ook hier weer gebruiken we $iConnect als tweede parameter. Daarvoor zet je
gewoon de query. Even een voorbeeldje van hoe een query gemaakt kan
worden. Vergeet niet deze telkens in een variabele te stoppen, want ook dit geeft
een waarde terug die je nodig hebt!
$iResult = mysql_query ("SELECT * FROM nieuws", $iConnect);
Dan hebben we nog een paar functies om alles op te halen en na te kijken. Deze
kun je enkel gebruiken bij een SELECT statement. De volgende code gaat
nakijken hoeveel rijen er zijn opgehaald. Daarvoor hebben we natuurlijk het
resultaat van de query nodig.
mysql_num_rows ($iResult); //Tellen hoeveel rijen er worden
opgehaald
© feneX – Cursus PHP & MySQL p 39
De volgende code gaat dan weer alles ophalen. Ook deze heeft natuurlijk het
resultaat van de uitgevoerde query nodig. Steek dit ook best in een variabele.
$aRow = mysql_fetch_assoc ($iResult); //Haalt de rijen op
Nog een aanvullende code om het duidelijker te maken.
<?php
print ("\n <ul>");
while ($aRow = mysql_fetch_assoc ($iResult))
{
print ("\n <li>". $aRow['Veldnaam']
."</li>");
}
print ("\n </ul>\n");
?>
© feneX – Cursus PHP & MySQL p 40
Hoofdstuk 6
PHP Data Objects _________________________________________________________________ Cursus PHP & MySQL Groep D
© feneX – Cursus PHP & MySQL p 41
E Hoofdstuk 1: PHP Data Objects
1.1 Inleiding
Tegenwoordig kun je er bij het ontwikkelen van een website bijna niet meer
omheen: het gebruik van een database. Of je nu bezig bent met een persoonlijke
website met gastenboek, een site voor je bedrijf met support forum of met een
ingewikkelde webshop; de basis van elke goede website wordt gevormd door een
database.
Er zijn vrij veel verschillende database systemen die je voor dit doeleinde kunt
gebruiken en allemaal kennen ze hun eigen functies. Aangezien elke database
anders is, vereist het werken ermee in PHP steeds een andere aanpak. Voor de
meest gebruikte database systemen waaronder MySQL, PostgreSQL en SQLite,
biedt PHP standaard ondersteuning. Echter zul je voor het benaderen van deze
verschillende databases altijd nog verschillende functies gebruiken.
Met de komst van PHP Data Objects (PDO) in PHP 5.1 hebben we de
beschikking over een uiterst handige extensie voor het benaderen van
verschillende databases. Naast het gebruik van een object georiënteerde notatie
biedt deze extensie ook nog andere voordelen. Het wordt namelijk een stuk
eenvoudiger om resultaat sets te verwerken, prepared statements uit te voeren
en transactions te gebruiken.
Nota: Vanaf PHP6 zullen de standaard database functies (mysql_*, pg_*, etc)
niet standaard meer ondersteund worden. Hoewel ze waarschijnlijk nog lange tijd
als extensie beschikbaar blijven, is het verstandig om nu al naar alternatieven te
kijken. Vooral als je een nieuw systeem aan het ontwikkelen bent is het gebruik
van PDO zeker een aanrader.
In dit hoofdstuk van de cursus zullen we dieper op de werking van de PDO-
extensie ingaan, en dit aan de hand van verschillende voorbeelden met
betrekking tot de belangrijkste functies. Voor een allesomvattende handleiding
over PDO verwijzen we je graag door naar php.net.
© feneX – Cursus PHP & MySQL p 42
1.2 Gebruik van de PDO-extensie
Voor het gebruik van de PDO extensie moeten we natuurlijk wel eerst weten of
de database die we willen gebruiken wel ondersteund wordt. Om PDO met een
bepaalde database te gebruiken, moeten we de juiste PDO-driver geïnstalleerd
hebben.
Controleren welke databasedrivers geïnstalleerd zijn
<?php
echo “<pre>”;
print_r(PDO::getAvailableDrivers());
echo “</pre>”;
?>
Dat levert dan het volgende resultaat op.
Array
(
[0] => sqlite2
[1] => pgsql
[2] => mysql
)
Dit betekent dat we op dit moment de juiste drivers geïnstalleerd hebben om te
werken met de databasesystemen MySQL, PostgreSQL en SQLite. Er worden
echter nog een boel andere databasesystemen ondersteund, zoals je uit
onderstaand lijstje kunt opmaken.
MySQL
PostgreSQL
SQLite
Microsoft SQL Server
ODBC
Oracle
Daar wij doorheen heel onze cursus met MySQL zullen werken, laten we de
andere systemen buiten beschouwing. Voor meer informatie over de
samenwerking tussen PDO en de andere systemen verwijzen we je opnieuw
door naar php.net.
© feneX – Cursus PHP & MySQL p 43
2.2.1 Verbinden met een Database
Het verbinden met een database met behulp van PDO is kinderlijk eenvoudig.
Het komt eigenlijk er op neer dat je een nieuwe instantie van de PDO klasse gaat
creëren. Natuurlijk moet je bij het instantiëren van de klasse wel de juiste
parameters meegeven.
Hieronder zie je hoe dat in z‟n werk gaat voor een verbinding met een MySQL
database.
<?php
$db = new PDO('mysql:host=localhost;dbname=test', 'user'
, 'password');
?>
Dat je voor het opzetten van een verbinding met elke willekeurige database
telkens dezelfde regel PHP kunt gebruiken, heeft te maken met het feit dat het
eigenlijke verbinden met de database achter de schermen afgehandeld wordt. De
meegegeven parameters worden door de extensie geïnterpreteerd en een
verbinding met de juiste database wordt gemaakt.
2.2.2 Sluiten van een Verbinding
Het sluiten van een verbinding is al even eenvoudig. Het enige dat je hier dient te
doen, is de instantie van de PDO-klasse vernietigen. Dat ziet er dan als volgt uit.
<?php
$db = NULL;
?>
Het handmatig sluiten van een databaseverbinding is in principe niet nodig.
Aangezien het bestaan van de verbinding direct afhangt van het bestaan van de
instantie van de PDO klasse, zal de verbinding verbroken worden zodra een
script eindigt. Het veelvuldig tussendoor sluiten en openen van verbindingen kan
tot een zeker performance verlies leiden, zeker als je verbinding maakt met een
externe database server.
© feneX – Cursus PHP & MySQL p 44
1.3 Uitvoeren van Queries Nu we weten hoe we verbinding maken met een database, kunnen we verder
gaan met het uitvoeren van queries. De PDO klasse heeft hiervoor twee
methodes beschikbaar, genaamd query() en exec().
Er zit een klein verschil in werking van deze twee methodes. De eerste, query(),
voert enkel de query uit en geeft een resultaat terug. De tweede daarentegen
voert de query uit en geeft daarnaast het aantal aangepaste rijen van een
INSERT, UPDATE of DELETE query terug.
Een SELECT query
<?php
$db = new PDO('mysql:host=localhost;dbname=test','user',
'password');
$sql = "SELECT naam FROM tabel";
$results = $db->query($sql);
foreach($results as $row)
{
echo $row['naam'] . ”<br />”;
}
?>
Allereerst maken we een nieuwe verbinding door een nieuwe instantie van de
PDO klasse aan te maken. Vervolgens voeren we met de query() methode een
SQL query uit. De resultaat set kunnen we daarna uitlezen met een for each loop.
Een UPDATE query
<?php
$db = new PDO('mysql:host=localhost;dbname=test','user',
'password');
$sql = "UPDATE tabel SET naam = 'Martijn' WHERE naam
= 'Pietje'";
$affected_rows = $db->exec($sql);
echo 'Aantal aangepaste rijen: '.$affected_rows;
?>
© feneX – Cursus PHP & MySQL p 45
Nu voeren we de query uit met de exec() methode die als resultaat dus een
aantal aangepaste rijen teruggeeft. Op deze manier kun je dus direct controleren
of er wel wat gewijzigd is.
Een INSERT query
<?php
$db = new PDO('mysql:host=localhost;dbname=test','user',
'password');
$sql = "
INSERT INTO tabel (naam)
VALUES ('Pieter-Jan')
";
$results = $db->exec($sql);
$insert_id = $db->lastInsertId();
echo “ID van laatst ingevoegde record: “ . $insert_id;
?>
Vanzelfsprekend ziet een INSERT query er precies hetzelfde uit. Vaak wil je na
een INSERT query het id van het laatst ingevoegde record weten. Met PDO kun
je dat achterhalen met de lastInsertId() methode zoals te zien is in het voorbeeld.
Natuurlijk moeten we niet vergeten om de in te voegen variabelen te beveiligen
om SQL-injectie te voorkomen. Waar we normaal altijd
mysql_real_escape_string() zouden gebruiken, kunnen we nu de quote()
methode van de PDO klasse gebruiken.
<?php
// Gegevens uit een gepost formulier verwerken
$db = new PDO('mysql:host=localhost;dbname=test','user',
'password');
$naam = $db->quote($_POST['naam']);
$sql = "
INSERT INTO tabel (naam)
VALUES ('".$naam."')
";
$db->exec($sql);
?>
© feneX – Cursus PHP & MySQL p 46
1.4 Foutafhandelingen
In de voorbeelden op de vorige pagina hebben we nog geen enkele vorm van
foutafhandeling toegepast, maar natuurlijk mag dat niet vergeten worden.
Foutafhandeling in een PHP-script is een van de belangrijkste dingen die er zijn.
PDO biedt drie verschillende manieren van foutafhandeling.
1. SILENT - Fouten worden onderdrukt en zullen handmatig opgevraagd
moeten worden.
2. WARNING - Gebruikt de error_handler van PHP en geeft een
E_WARNING.
3. EXCEPTION - Gebruikt PDOException klasse.
Van dit lijstje is SILENT de standaard instelling. Dat betekent dat je altijd de code
en informatie van de foutmelding met de methodes errorInfo() en errorCode() zult
moeten ophalen om te controleren of er fouten opgetreden zijn. Een uitzondering
op deze regel is een fout bij het verbinden met de database, oftewel het
instantiëren van de PDO klasse. In dat geval wordt er een PDOException object
aangemaakt dat op te vangen is met een try/catch combinatie. Dit staat
beschreven in onderstaand voorbeeld.
<?php try {
$db = new PDO('mysql:host=localhost;dbname=bestaat_niet','user','password');
} catch(PDOException $e) {
echo $e->getMessage(); }
?>
Dit zal de volgende melding geven:
SQLSTATE[42000] [1049] Unknown database 'bestaat_niet'
Zoals we zien krijgen we netjes een melding dat de opgegevens database niet
bestaat.
Het is belangrijk om steeds op deze manier te controleren of een verbinding
gelukt is. Mocht er namelijk iets fout gaan en de fout wordt niet afgehandeld, dan
zal PHP een backtrace weergeven waarin mogelijk alle details van de
databaseverbinding staan. Dit omvat dus mogelijk ook gegevens als
gebruikersnaam en wachtwoord van je database!
© feneX – Cursus PHP & MySQL p 47
Als we met de standaard instelling – SILENT – een fout maken in een query die
we uitvoeren, krijgen we daar geen foutmelding van te zien. Bijvoorbeeld:
<?php try {
$db = new PDO('mysql:host=localhost;dbname=test','user','password'); $sql = "SELECT naam FROM bestaat_niet"; $results = $db->query($sql); foreach($results as $row) {
echo $row['naam'] . “<br />”; }
} catch(PDOException $e) {
echo $e->getMessage(); }
?>
De enige melding die we nu krijgen is:
Warning: Invalid argument supplied for foreach()
We zien dat $results dus geen geldig argument voor de foreach() is en dus doet
dat ons vermoeden dat er iets fout gegaan is met de query. Maar als dat zo is,
zouden we daar graag een foutmelding van krijgen.
In dat geval zouden we ervoor kunnen kiezen om de WARNING instelling te
gebruiken. Dan wordt er naast het aanmaken van een error code ook een
standaard E_WARNING melding gegeven.
Het type foutafhandeling kunnen we instellen door het type toe te kennen aan het
attribuut dat de foutafhandeling bepaald. Dit doen we met de setAttribute()
methode.
Op de volgende pagina vind je een voorbeeld van foutafhandeling met een
WARNING.
<?php try {
$db = new PDO('mysql:host=localhost;dbname=test','user','password'); $db-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERR MODE_WARNING); $sql = "SELECT naam FROM bestaat_niet";
© feneX – Cursus PHP & MySQL p 48
$results = $db->query($sql); foreach($results as $row) {
echo $row['naam'] . “<br />”; }
} catch(PDOException $e) {
echo $e->getMessage(); }
?>
De foutmelding die nu gegeven wordt:
Warning: PDO::query() [function.PDO-
query]: SQLSTATE[42S02]: Base table or view not found: 1146
Table 'test.bestaat_niet' doesn‟t exist.
Warning: Invalid argument supplied for foreach().
We zien dat er zowel een foutmelding gegeven wordt op het punt waar de query
uitgevoerd wordt als op de plaats van de foreach(). Zoals je altijd te werk gaat
met debuggen, los je nu ook eerst de eerste fout op. Dit zal in dit geval ook de
tweede foutmelding laten verdwijnen.
Als laatste instelling hebben we EXCEPTION over. In dat geval zal er net zoals in
het geval van de fout met de verbinding, voor de fout een PDOException object
aangemaakt worden. De gegevens van deze foutmelding kunnen we wederom
uitlezen in het catch gedeelte van het script.
© feneX – Cursus PHP & MySQL p 49
<?php
try
{
$db = new PDO('mysql:host=localhost;dbname=tes
t','user','password');
$db->
setAttribute(PDO::ATTR_ERRMODE, PDO::ERR
MODE_EXCEPTION);
$sql = "SELECT naam FROM bestaat_niet";
$results = $db->query($sql);
foreach($results as $row)
{
echo $row['naam'] . “<br />”;
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
?>
De volgende foutmelding werd gegenereerd:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.
bestaat_niet' doesn't exist.
We zien dat we hier alleen een foutmelding op de query te zien krijgen en geen
verdere meldingen dat bijvoorbeeld het argument van de foreach() niet juist is.
Zoals gewoonlijk kunnen we natuurlijk het hele PDOException object uitkleden en
alle informatie over een fout naar boven halen, dit staat beschreven in het
voorbeeld op de volgende pagina.
© feneX – Cursus PHP & MySQL p 50
<?php
try
{
$db = new PDO('mysql:host=localhost;dbname=tes
t','user','password');
$db->
setAttribute(PDO::ATTR_ERRMODE, PDO::ERR
MODE_EXCEPTION);
$sql = "SELECT naam FROM bestaat_niet";
$results = $db->query($sql);
foreach($results as $row)
{
echo $row['naam'] . “<br />”;
}
}
catch(PDOException $e)
{
echo “<pre>”;
echo “Regelnummer: “ . $e->getLine() . “<br>”;
echo “Bestand: “ . $e->getFile() . “<br />”;
echo “Foutmelding: “ . $e->getMessage() . “<br/>”;
echo “</pre>”;
}
?>
De enige melding die we nu krijgen is:
Regelnummer: 8
Bestand: Dummy File Path
Foutmelding: SQLSTATE[42S02]: Base table or view not found: 11
46 Table 'test.bestaat_niet' doesn't exist
Wij zullen steeds de Exception gebruiken als foutafhandeling. Je gebruikt de
try/catch syntax immers toch al om te controleren of de verbinding gelukt is.
Daarnaast krijg je alle opvolgende foutmeldingen die het gevolg zijn van een
foute query niet te zien en kun je helemaal zelf bepalen welke informatie je wel
wilt tonen.
© feneX – Cursus PHP & MySQL p 51
1.5 Prepared Statements
Op dit punt zul je misschien denken dat de PDO-extensie niet veel meer biedt
dan de mogelijkheid om te verbinden met meerdere database systemen en het
uitvoeren van databasegerelateerde taken. Dat is zeker niet het geval aangezien
PDO met een aantal mooie features komt, waaronder het werken met prepared
statements.
Deze prepared statements bieden de programmeur de mogelijkheid tot het
creëren van queries die veiliger zijn, waarvan de performance beter is en die
eenvoudiger te noteren zijn. Het grote voordeel van prepared statements is dat
een bepaalde query op een efficiënte manier vele malen achter elkaar uitgevoerd
kan worden.
Bij het gebruik van prepared statements wordt er allereerst een template van de
uit te voeren query naar de server gestuurd. Deze wordt door de server
gecontroleerd op syntax fouten en uitgevoerd om te controleren of de query
logisch is. Vervolgens wordt deze opgeslagen in een speciale buffer.
Op het moment dat de query daadwerkelijk uitgevoerd moet worden, stuur je de
in de query in te vullen gegevens naar de database. Vervolgens wordt een
complete query gevormd en uitgevoerd.
Op de volgende pagina vind je een voorbeeld van een prepared INSERT
statement.
© feneX – Cursus PHP & MySQL p 52
<?php try {
$db = new PDO('mysql:host=localhost;dbname=test','user','password'); $db-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERR MODE_EXCEPTION);
$sql = "
INSERT INTO tabel (naam) VALUES (:naam) “;
$stmt = $db->prepare($sql); $stmt-> bindParam(':naam', $naam, PDO::PARAM_STR); $naam = “Nick”; $stmt->execute();
} catch(PDOException $e) {
echo “<pre>”; echo “Regel: “ . $e->getLine() . “<br />”; echo “Bestand: “ . $e->getFile() . “<br />”; echo “Foutmelding: “ . $e->getMessage(); echo “</pre>”;
} ?>
In dit script hebben we eerst een template gemaakt van de INSERT query die we
willen gebruiken. Het stukje ':naam' in de template is een zogenaamde parameter
marker of placeholder en geeft de plaats aan waar straks een variabele ingevuld
gaat worden.
Vervolgens roepen we de prepare() methode aan om de query naar de server te
sturen en te laten controleren. Als dat gelukt is, gebruiken we de bindParam()
methode. Met deze methode koppelen we een bepaalde variabele aan een
bepaalde placeholder. Op die manier weet PHP straks welke variabele hij onder
welke naam naar de server moet sturen zodat deze het begrijpt. De optionele
derde parameter van deze methode geeft aan als wat voor type de variabele
behandeld moet worden, in dit geval dus een string.
Nadat we de variabele vervolgens een waarde hebben gegeven, sturen we alles
wederom naar de server met de execute() methode. Als alles goed is gegaan
krijgen we geen foutmeldingen en zal er een nieuw record ingevoegd zijn.
Natuurlijk is het ook mogelijk om meerdere placeholders te gebruiken om
meerdere gegevens in te voeren. En daarnaast kunnen we ook nog eens
meerdere queries achter elkaar uitvoeren.
© feneX – Cursus PHP & MySQL p 53
Hieronder vind je een voorbeeld van een prepared statement met meerdere
gegevens en meerdere queries.
<?php try {
$db = new PDO('mysql:host=localhost;dbname=test','user','password'); $db-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERR MODE_EXCEPTION); $personen = array(
array( 'naam' => 'Martijn', 'email' => '[email protected]', 'leeftijd' => 19 ), array( 'naam' => 'Joris', 'email' => '[email protected]', 'leeftijd' => 20 ), array( 'naam' => 'Maarten', 'email' => [email protected]', 'leeftijd' => 18 )
); $sql = "
INSERT INTO tabel (naam, leeftijd, email) VALUES (:naam, :leeftijd, :email) ";
$stmt = $db->prepare($sql); $stmt-> bindParam(':naam', $naam, PDO::PARAM_STR); $stmt-> bindParam(':email', $email, PDO::PARAM_STR); $stmt-> bindParam(':leeftijd', $leeftijd, PDO::PARAM_INT); foreach($personen as $persoon) {
$naam = $persoon['naam']; $email = $persoon['email']; $leeftijd = $persoon['leeftijd']; $stmt->execute();
} } catch(PDOException $e) {
echo “<pre>”; echo “Regel: “ . $e->getLine() . “<br />”; echo “Bestand: “ . $e->getFile(). “<br />”; echo “Foutmelding: “ . $e->getMessage(); echo “</pre>”;
} ?>
Voor elke placeholder die we in de query template aangegeven hebben, roepen
we de bindParam() methode aan om een variabele te koppelen.
© feneX – Cursus PHP & MySQL p 54
We lezen de array met gegevens uit met een for each loop, geven de gekoppelde
variabelen een waarde en voeren de statement uit met de execute() methode. Je
ziet dat er geen gebruik gemaakt wordt van de quote() methode om in te voegen
strings te beveiligen. Dit is niet nodig aangezien de execute() methode al zorgt
voor een veilige afhandeling van de gegevens.
Daarnaast is er nog een andere manier waarop we de prepared statement uit
kunnen voeren. We kunnen alle gegevens namelijk ook in een array als
parameter meegeven aan de execute() methode van het statement.
Hieronder zie je hoe we statements met een gegevensarray als parameter
zouden kunnen uitvoeren.
<?php
try
{
$db = new PDO('mysql:host=localhost;dbname=tes
t','user','password');
$db->
setAttribute(PDO::ATTR_ERRMODE, PDO::ERR
MODE_EXCEPTION);
$personen = array(
array(
':naam' => 'Martijn',
':email' => '[email protected]',
':leeftijd' => 19 ),
array(
':naam' => 'Joris',
':email' => '[email protected]',
':leeftijd' => 20 ),
array(
':naam' => 'Maarten',
':email' => '[email protected]',
':leeftijd' => 18 )
);
$sql = "
INSERT INTO tabel (naam, leeftijd, email)
VALUES (:naam, :leeftijd, :email)
";
$stmt = $db->prepare($sql);
© feneX – Cursus PHP & MySQL p 55
foreach($personen as $persoon)
{
$stmt->execute($persoon);
}
}
catch(PDOException $e)
{
echo “<pre>”;
echo “Regel: “ . $e->getLine() . “<br />”;
echo “Bestand: “ . $e->getFile() . “<br />”;
echo “Foutmelding: “ . $e->getMessage();
echo ”</pre>”;
}
?>
Op de volgende pagina vind je nog een voorbeeld, waar we een UPDATE query
gaan uitvoeren met een prepared statement. Dit gelijkt erg op het INSERT
voorbeeld, maar kent toch één belangrijk verschil. Bij een UPDATE of DELETE
query is het namelijk altijd van belang om te controleren of er wel degelijk rijen
aangepast zijn.
Met de methode rowCount() kunnen we het aantal aangepaste rijen van het
laatste uitgevoerde statement ophalen. Mocht dit gelijk zijn aan 0 dan creëren we
een nieuw PDOException object met de betreffende melding
© feneX – Cursus PHP & MySQL p 56
<?php
try
{
$db = new PDO('mysql:host=localhost;dbname=tes
t','user','password');
$db->
setAttribute(PDO::ATTR_ERRMODE, PDO::ERR
MODE_EXCEPTION);
$personen = array('Martijn', 'Maarten');
$sql = "
UPDATE
tabel
SET
email = 'geen mail'
WHERE
naam = :naam
";
$stmt = $db->prepare($sql);
$stmt->
bindParam(':naam', $naam, PDO::PARAM_STR);
foreach($personen as $persoon)
{
$naam = $persoon;
$stmt->execute();
if($stmt->rowCount() == 0)
{
throw new PDOException(“Er zijn ge
en rijen gewijzigd in de UPDATE que
ry met naam: “ . $naam);
}
}
}
catch(PDOException $e)
{
echo '<pre>';
echo 'Regel: '.$e->getLine().'<br>';
echo 'Bestand: '.$e->getFile().'<br>';
echo 'Foutmelding: '.$e->getMessage();
echo '</pre>';
}
?>
© feneX – Cursus PHP & MySQL p 57
Naast het invoegen, updaten en verwijderen van records met een prepared
statement, is het ook mogelijk om een SELECT query uit te voeren.
Hoewel een het uitvoeren van een prepared SELECT statement veel lijkt op de
voorbeelden hierboven, werkt het toch net iets anders. We hebben hier namelijk
te maken met gegevens die we uit de database ophalen, dus zullen we die
gegevens op een bepaalde manier zichtbaar moeten maken.
Hieronder vind je een voorbeeld waarbij we de gegevens uitlezen met een
fetch().
<?php try {
$db = new PDO('mysql:host=localhost;dbname=test','user','password'); $db-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERR MODE_EXCEPTION);
$sql = "SELECT naam FROM tabel WHERE leeftijd > :leeftijd";
$stmt = $db->prepare($sql); $stmt-> bindParam(':leeftijd', $leeftijd, PDO::PARAM_INT);
$leeftijd = 18; $stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['naam'] . “<br />”; }
} catch(PDOException $e) {
echo “<pre>”; echo “Regel: “ . $e->getLine() . “<br />”; echo “Bestand: “ . $e->getFile() . “<br />”; echo “Foutmelding: “ . $e->getMessage(); echo “</pre>”;
} ?>
Dit geeft als resultaat iets als:
Martijn - 19 Joris - 20
Tot aan de execute() methode is dit script precies hetzelfde als voorgaande
voorbeelden. Maar zoals ik al zei moeten we de resultaten van de query natuurlijk
zichtbaar kunnen maken. Hier gebruiken we de fetch() methode voor.
© feneX – Cursus PHP & MySQL p 58
Aan de fetch() methode kunnen we optioneel een parameter meegeven om aan
te geven hoe we willen dat de rijen gefetched worden. Dit is vergelijkbaar met de
optionele parameter van de mysql_fetch_array() functie.
De belangrijkste beschikbare parameters zijn:
PDO::FETCH_ASSOC - Een rij als associatieve array
PDO::FETCH_NUM - Een rij als numerieke array
PDO::FETCH_BOTH - Een rij zowel associatief als numeriek te
gebruiken (standaard)
In tegenstelling tot bijvoorbeeld de MySQLi extensie kent PDO geen methode om
het aantal rijen in een resultaatset te bepalen. Wil je dit aantal weten, dan zul je
een extra query uit moeten voeren om dat aantal te bepalen. Het makkelijkste is
het om hier een query met COUNT() voor te gebruiken: zie onderstaand
voorbeeld.
<?php try {
$sql = "SELECT COUNT(naam) FROM tabel WHERE leeftijd > 18"; $row = $db->query($sql)-> fetch(PDO::FETCH_ASSOC); echo $row['aantal']; // Output: 2
} catch(PDOException $e) {
echo “<pre>”; echo “Regel: “ . $e->getLine() . “<br />”; echo “Bestand: “ . $e->getFile() . “<br />”; echo “Foutmelding: “ . $e->getMessage(); echo “</pre>”;
} ?>
In dit voorbeeld gebruiken we query() om een eenvoudige query uit te voeren en
fetch() om het resultaat van de query in een array te zetten. De variabele
$row['aantal'] zal in dit geval het aantal rijen in de resultaat set van de query
bevatten.
Verder met het fetchen van gegevens. Een tweede methode die we daarvoor
kunnen gebruiken is fetchAll(), deze zullen we aan de hand van een voorbeeld
verder toelichten op de volgende pagina.
© feneX – Cursus PHP & MySQL p 59
<?php try {
$db = new PDO('mysql:host=localhost;dbname=test','user','password'); $db-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERR MODE_EXCEPTION); $sql = "SELECT naam FROM tabel WHERE leeftijd > :leeftijd"; $stmt = $db->prepare($sql); $stmt->bindParam(':leeftijd', $leeftijd); $leeftijd = 18; $stmt->execute(); $result = $stmt->fetchAll(); foreach($result as $row) {
echo $row['naam'] . “<br />”; }
} catch(PDOException $e) {
echo “<pre>”; echo “Regel: “ . $e->getLine() . “<br />”; echo “Bestand: “ . $e->getFile() . “<br />”; echo “Foutmelding: “ . $e->getMessage(); echo “</pre>”;
} ?>
Wederom zien we hier hetzelfde resultaat:
Martijn - 19 Joris - 20
De fetchAll() methode doet dus niets meer dan alle rijen uit de resultaat set onder
een nieuwe key in een array zetten. Vervolgens kunnen we deze array met een
for each loop uitlezen.
Aan de fetchAll() methode kunnen we natuurlijk ook weer een parameter
meegeven om aan te geven hoe de resultaten gefetched moeten worden.
© feneX – Cursus PHP & MySQL p 60
1.6 Transacties
Transacties klinken de doorgewinterde databasegebruiker waarschijnlijk zeer
bekend in de oren, maar niet iedereen zal weten wat je met dit principe kunt.
Simpel gezegd heb je bij transacties in een database de mogelijkheid om een
reeks queries uit te voeren zonder dat je eventuele aanpassingen definitief
doorvoert. Aan het einde van deze reeks kun je COMMIT gebruiken om de
wijzigingen definitief door te voeren of ROLLBACK om alle wijzigingen terug te
draaien.
De PDO extensie biedt ons drie methodes voor het werken met transacties:
beginTransaction(), commit() en rollBack(). De eerste methode roepen we aan
het begin aan, deze zorgt ervoor dat autocommit uitgezet wordt en dat queries
pas definitief doorgevoert worden zodra commit() aangeroepen wordt. De
rollback() methode kunnen we gebruiken om gemaakte wijzigingen terug te
draaien mocht er een fout optreden.
<?php try {
$db = new PDO('mysql:host=localhost;dbname=test','user','password'); $db-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERR MODE_EXCEPTION); $db->beginTransaction(); $db->query("INSERT INTO tabel (naam) VALUES ('Martijn')"); $db->query("INSERT INTO tabel (naam) VALUES ('Nick')"); $db->query("INSERT INTO tabel (naam) VALUES ('Maarten')"); $db->query("INSERT INTO tabel (naam) VALUES ('Joris')"); $db->commit();
} catch(PDOException $e) {
if(isset($db)) {
$db->rollBack(); } echo '<pre>'; echo 'Regel: '.$e->getLine().'<br>'; echo 'Bestand: '.$e->getFile().'<br>'; echo 'Foutmelding: '.$e->getMessage(); echo '</pre>';
} ?>
© feneX – Cursus PHP & MySQL p 61
We zien hier inderdaad de drie methodes waar ik het al eerder over had terug.
Na beginTransaction() voeren we een viertal INSERT queries uit. Als alles goed
gaat, voeren we de wijzigingen definitief door met commit(). Mocht er een fout
optreden dan vangen we die op in het catch gedeelte van het script en draaien
we alle reeds gemaakte wijzigingen terug.
We moeten we even controleren of $db bestaat, aangezien dit gedeelte ook
fouten in de verbinding opvangt. Als daar een fout in optreedt, zal $db niet
bestaan en zal het aanroepen van rollback() niet mogelijk zijn.
Hoewel ik hier nu vier losse queries gebruikt heb, kunnen we deze natuurlijk ook
weer vervangen door een prepared statement. Dat zou een nettere oplossing
geven.
Een ander goed voorbeeld om het gebruik van transacties te verduidelijken is een
geldtranscatie tussen twee bankrekeningen van respectievelijk persoon A en B.
Er zal 500 euro overgemaakt worden van persoon A naar persoon B, maar
persoon A mag natuurlijk geen negatief saldo krijgen.
Daarnaast kan het totale saldo uit de tabel nooit groter of kleiner worden, er kan
immers geen geld ontstaan of verdwijnen. Dat betekent dat de ene query niet
uitgevoerd mag worden zonder dat de ander ook uitgevoerd wordt. Duidelijk iets
om een transactie voor te gebruiken.
Dit voorbeeld zie je uitgewerkt over de laatste pagina‟s van dit hoofdstuk.
<?php try {
$db = new PDO('mysql:host=localhost;dbname=test','user','password'); $db-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERR MODE_EXCEPTION); $queries[] = "UPDATE rekeningen SET saldo = saldo - 500 WHERE klant = 'A'"; $queries[] = "UPDATE rekeningen SET saldo = saldo + 500 WHERE klant = 'B'"; $controle = "SELECT saldo FROM rekeningen WHERE klant = 'A'"; $db->beginTransaction();
© feneX – Cursus PHP & MySQL p 62
foreach($queries as $query) {
$affected = $db->exec($query); if($affected == 0) {
throw new PDOException(“Update query niet geslaagd: “ . $query);
} } $result = $db->query($controle); $row = $result->fetchAll(); if($row[0]['saldo'] < 0) {
throw new PDOException(“Saldo niet toereikend”);
} $db->commit(); echo “<pre>” . print_r (get_class_methods($db) ,true) . “</pre>”;
} catch(PDOException $e) {
if(isset($db)) {
$db->rollBack(); } echo “<pre>”; echo “Regel: “ . $e->getLine() . “<br />”; echo “Bestand: “ . $e->getFile() . “<br />”; echo “Foutmelding: “ . $e->getMessage(); echo “</pre>”;
} ?>
We beginnen met het uitvoeren van de UPDATE queries. Mocht daar een fout in
optreden, dan willen we dat natuurlijk weten dus maken we in dat geval een
nieuw PDOException object aan.
Daarna voeren we de controle query uit en controleren het resultaat. Als dit
kleiner is dan 0 heeft persoon A een negatief saldo. Omdat dit niet toegestaan is,
gooien we er weer een foutmelding tegenaan zodat alle wijzigingen
teruggedraaid worden.
Op deze manier zorgt onze transactie ervoor dat er dus nooit een query zonder
de ander uitgevoerd kan worden en dat alles teruggedraaid wordt als er ergens
een negatief saldo ontstaat.
© feneX – Cursus PHP & MySQL p 63
Hoofdstuk 7
Oefeningen - Oplossingen _________________________________________________________________ Cursus PHP & MySQL Groep D
© feneX – Cursus PHP & MySQL p 64
Hoofdstuk 7: Oefeningen
7.1 Oefeningen PHP Om de theorie die we in deze cursus gezien te hebben iets beter in de vingers te
krijgen, hebben we een aantal oefeningen voorzien. We hebben een drietal
simpele oefeningen en tien herhalingsoefeningen gebundeld. Verder hebben we
ook nog twee voorbeelden met betrekking tot MySQL toegevoegd.
7.1.1 Beginnersoefeningen
Oefening 1
Schrijf een log-in script. Je kunt enkel ingelogd worden als de gebruikersnaam
admin is en het paswoord demo. Voorzie ook enkele foutmeldingen.
Oefening 2
Schrijf een simple e-mail formulier met een naam, e-mail adres, onderwerp en
een bericht. Voorzie ook hier enkele foutmeldingen.
Oefening 3
Schrijf een script om de tafels van vermenigvuldiging weer te geven.
7.1.2 Herhalingsoefeningen
Extra uitleg bij enkele functies:
De mail functie in PHP:
mail ( string $to , string $subject , string $message [, string $addit
ional_headers [, string $additional_parameters ]] )
De date functie:
string date ( string $format [, int $timestamp ] )
Oefening 1
Geef Hello World op het scherm. Doe dit op twee manieren: zowel met behulp
van een functie, als met behulp van een variabele.
Oefening 2
Maak een selectiestructuur waarbij wordt nagegaan of een getal even of oneven
is. Gebruik de twee verschillende selectiestructuren die je kent.
Oefening 3
Bereken de absolute waarde van een getal.
© feneX – Cursus PHP & MySQL p 65
Oefening 4
Maak in XHTML Strict 1.0 een ordered list, een unordered list, een definition list
en een tabel. Als je nog niet met HTML kunt werken, is dit de moment om je
ermee vertrouwd te maken.
Oefening 5
Maak een mailformulier waarbij de gebruiker een goede foutmelding krijgt.
Gebruik dit keer een array van foutmeldingen.
Oefening 6
Druk alle waarden in een array af. Doe dit op zo veel mogelijk verschillende
manieren. Met andere woorden: maak gebruik van elke lus waarmee je dit
probleem denkt te kunnen oplossen.
Oefening 7
Maak een functie om een array met getallen bij elkaar op te tellen.
Oefening 8
Maak een kalender van de huidige maand. Extra: Voorzie dat je van maand kunt
wisselen.
Oefening 9
Maak een klasse Test met een functie om een tekst weg te schrijven op het
scherm.
Oefening 10
Maak een klasse Math met enkele wiskundige berekeningen.
Bovenstaande oefeningen maakten werden gebruikt als studiemateriaal bij het
maken van de cursus en het leren begrijpen van de stof. Hieronder vind je iet of
wat meer gevorderde oefeningen. Te beginnen met een relatief simpele PHP
oefening, om te zien of je de basis op z‟n minst onder de knie hebt. Vervolgens
komt MySQL uitgebreid aan bod.
© feneX – Cursus PHP & MySQL p 66
Vaardigheidstest PHP
Oefening 1: Log-in Formulier
Schrijf een log-in formulier in HTML en PHP dat een gebruiker inlogt wanneer zijn
gebruikersnaam Administrator is en het paswoord feneX. De hoofdletters mogen
niet genegeerd worden. Wanneer je de correcte gebruikersnaam en het correcte
paswoord hebt opgegeven, krijg je een melding dat je succesvol bent ingelogd en
is het HTML form niet langer te zien op de pagina. Voorzie foutmeldingen
wanneer je foutieve invoer levert op dezelfde pagina als de HTML-form.
Oefeningen MySQL
Oefening 1 – Database feneX
Maak een database feneX met alle groepsleden van onze projectgroep. We
moeten velden hebben voor naam, voornaam, functie en score op de
vaardigheidstest PHP. Druk met behulp van MySQL de hele database af in een
tabel.
Oefening 2 – feneX eXtended
Breid de voorgaande oefening uit door een aantal dingen toe te voegen. Zorg
ervoor dat we nieuwe leden kunnen toevoegen (1) en bestaande leden kunnen
aanpassen (2). Denk aan invoercontrole bij het toevoegen of updaten van een
bestaande user. Gebruik hierbij de gekende selectiestructuren en eventuele
functies die je kent (zoals isset).
Voeg vervolgens een functie in PHP toe die het gemiddelde van de punten van
alle studenten berekent (3).
N.B.: Splits bovenstaande oefening op in drie delen, werk steeds met aparte .php bestanden.
© feneX – Cursus PHP & MySQL p 67
7.2 Oplossingen PHP
De oplossingen van alle oefeningen in deze cursus zijn eveneens voorhanden.
Deze zijn als .php bestand aan deze cursus toegevoegd in een .RAR bestand.
Cursusoefeningen en Voorbeelden
OplOef1.php
OplOef2.php
OplOef3.php
OplHerhOef1.php
OplHerhOef2.php
OplHerhOef3.php
OplHerhOef4.php
OplHerhOef5.php
OplHerhOef6.php
OplHerhOef7.php
OplHerhOef8.php
OplHerhOef9.php
OplHerhOef10.php
MySQLclassDB.php
MySQLindex.php
PHP Vaardigheidstest en MySQL
feneX Oef 1.1.php
feneX Oef 2.1.php
feneX Oef 2.2.php
feneX Oef 2.3.php
feneX Oef 2.4.php
© Artesis – Cursus PHP & MySQL p 69
Bronvermelding
Bij het schrijven van deze cursus hebben we een aantal verschillende bronnen
geraadpleegd, zowel websites als handboeken. Hieronder vind je de
verschillende werken die we gebruikt hebben bij het opstellen van onze cursus
PHP & MySQL.
Bibliografie
1. CONVERSE, T., e.a. PHP5 and MySQL Bible. Indiana, Wiley, 2004.
2. TERRYN, S. PHP 5 in 10 minuten. Nijmegem, Pearson, 2006.
3. VAN EMDE BOAS, G. PHP 5 en MySQL De Basis. Amsterdam, Pearson, 2006.
Websites
1. http://www.php.net/manual/en/index.php
2. http://www.w3schools.com/php/default.asp
3. http://www.sitemasters.be/tutorials/4/1/PHP
4. http://www.devarea.nl/wiki/page/Basis-handleiding-PHP.html
5. http://phphulp.jorendewit.nl/home/