2 Een website bouwen - Welkom bij Pearson Benelux BV

34
De belangrijkste punten van bonushoofdstuk 2 X Nieuwe websites moeten toegankelijk zijn van breedbeeld pc tot smartphone. X Het sleutelwoord voor brede toegankelijkheid is zichzelf aanpassend webontwerp (Engels: respon- sive web design). X Een raamwerk vergemakkelijkt het opzetten van flexibele en uitbreidbare websites. X U kunt een pagina structuur geven en verfraaien door middel van stijlbladen. X Een login-module maakt het mogelijk de toegang toet uw website, of delen daarvan, te reguleren. 2 Een website bouwen

Transcript of 2 Een website bouwen - Welkom bij Pearson Benelux BV

Page 1: 2 Een website bouwen - Welkom bij Pearson Benelux BV

De belangrijkste punten van bonushoofdstuk 2

X Nieuwe websites moeten toegankelijk zijn van breedbeeld pc tot smartphone.

X Het sleutelwoord voor brede toegankelijkheid is zichzelf aanpassend webontwerp (Engels: respon-sive web design).

X Een raamwerk vergemakkelijkt het opzetten van flexibele en uitbreidbare websites.

X U kunt een pagina structuur geven en verfraaien door middel van stijlbladen.

X Een login-module maakt het mogelijk de toegang toet uw website, of delen daarvan, te reguleren.

2 Een website bouwen

Page 2: 2 Een website bouwen - Welkom bij Pearson Benelux BV

wat leert u in dit hoofdstuk?

We leggen de basis voor een websiteraamwerk.

Met CSS kunnen we onze pagina een flexibele structuur geven.

We gebruiken CSS3 en mediaquery’s om zichzelf aanpassende sites te maken.

We maken een template voor een pagina volgens een vloeiend rasterontwerp, dat zorgt voor een pagina volgens de principes van ‘zichzelf aanpassend webontwerp’.

We maken een loginmodule met data-base tabellen waarin gebruikersgegevens met versleutelde wachtwoorden staan en autorisatie gegeven kan worden volgens de rol die een gebruiker kan hebben.

We beperken ons in dit hoofdstuk tot browser-server communicatie zonder Ajax.

Page 3: 2 Een website bouwen - Welkom bij Pearson Benelux BV

28

PHP EN MYSQL de basis

2.1 Bouwtechniek voor een websiteEen jaar of vijf geleden was de wereld een stuk simpeler wat websitebouwen betreft. U maakte de structuur in HTML, hier en daar mocht er een plaatje in en u gaf het geheel een kleurtje met CSS. Bij het maken van de structuur was het de voornaamste vraag of u dit zou opzetten met behulp van frames, met tabellen of met CSS. Frames zijn totaal uit de mode: in HTML 5 kunt u ze niet eens meer gebruiken. Het gebruik van tabellen werd altijd al minachtend bekeken, hoewel dat eigenlijk ontzettend handig was, omdat tabel-len zich netjes voegen naar hun omgeving en keurig schalen als dat nodig is. Hoe moeten we een website dan vormgeven? Met behulp van CSS.

Destijds was CSS nogal lastig omdat elke browser verschillende ideeën had over hoe met de CSS om te gaan. Dat leidde weer tot JavaScript-pakketten die daar oplossingen voor boden, maar die hadden ook problemen met de browsercompatibiliteit. Een gevolg was vaak dat websites alleen goed te zien waren in Internet Explorer (IE), of juist niet, omdat IE veel afwijkingen heeft ten opzichte van andere browsers.

Inmiddels zijn er snellere browsers die latere versies van CSS begrijpen (CSS3) en er zijn goede JavaScript-bibliotheken zoals jQuery, die dynamische CSS-functies bieden en die vaak verschillen tussen browsers weten op te lossen. Er is steeds meer functionaliteit voor HTML 5 en er zijn steeds meer browsers die HTML 5 ondersteunen. Alleen als uw klant Internet Explorer 6 (IE6) gebruikt, zou u nog wel een probleem kunnen hebben, maar voor sommige functies zijn er pakketten om dat te omzeilen.

H T ML 5

HTML 5 biedt een aantal interessante nieuwe functie, zoals canvas, waarop u kunt tekenen, video- en audio-elementen, waardoor u geen Flash meer nodig hebt om deze media af te spelen, nieuwe structurele elementen, nieuwe formulier elementen, locale opslag en meer.

Kunt u nu HTML 5 gaan gebruiken? Helaas is er nog geen browser die HTML 5 compleet onder-steunt, en oudere browsers zoals het toch nog veel gebruikte IE6 doen dat helemaal niet. De spe-cificatie is eigenlijk ook nog in ontwikkeling. Voor mobiele toepassingen is HTML 5 echter zeker aan te bevelen.

We kiezen voor onze voorbeelden in dit hoofdstuk een middenweg: we gebruiken rede-lijk modern CSS dat misschien door IE6 niet altijd begrepen wordt, maar HTML 5 laten we niet zien, alhoewel alles wat we maken wel gewoon werkt in HTML 5 (behalve die frames dan, maar die gebruiken we niet).

Andere zaken die u misschien graag zou willen weten, is hoe een link te maken naar Facebook, Twitter en andere sociale media sites. Op het web zijn genoeg uitgebreide voorbeelden te vinden, mocht u sociale media in uw website willen gebruiken.

Page 4: 2 Een website bouwen - Welkom bij Pearson Benelux BV

29

2 Een website bouwen

2.1.1 Een raamwerk voor een webpagina

Stelt u zich voor dat u een site maakt van een pagina of tien voor een vereniging of zo. Net als alles klaar is, zegt de voorzitter dat de kleur anders moet. Als u alle tien pagina’s veranderd hebt, dan komt de secretaris met een andere kopregel, daarna wil iemand een ander logo en vervolgens moeten er nieuwe menuopties bij. Ziet u de bui hangen?

Als u de veranderingen hebt aangebracht, dan zegt de penningmeester dat de site er niet uitziet op zijn smartphone. Wat te doen? U zou kunnen overwegen om een pc-versie van uw site te maken, en ook een tablet- en een smartphoneversie. Er zijn genoeg websites die deze aanpak volgen, maar met de vervagende grenzen tussen pc, laptop, netbook, tablet en smartphone zijn de resultaten vaak niet ideaal. Mocht u in het bezit zijn van een tablet zoals een iPad, dan hebt u vast meer dan eens een mobiele site voor uw neus gekregen met hele brede regels en weinig tekst, terwijl een gewone versie veel hanteer-baarder zou zijn geweest. We willen niet in deze kuil vallen, daarom kiezen we er voor om de laatste mode te volgen: responsive web design, ofwel zichzelf aanpassend webont-werp.

Een ander probleem is dat sommige veel gebruikte technologieën, met name Flash, op veel mobiele apparaten, met name die van Apple, niet te zien zijn. Voor sommige functio-naliteit kunt u vervanging vinden met HTML5. We verwachten in de eerstkomende jaren een stortvloed aan nieuwe hulpmiddelen om u te helpen mooie sites te maken die overal en op elk apparaat toegankelijk zijn.

RESPoNSivE wEb DESigN

Met de principes van zichzelf aanpassend webontwerp is het mogelijk een website te maken die op alle apparaten leesbaar en bruikbaar blijft. Zichzelf aanpassend webontwerp bestaat uit drie onderdelen:- Flexibele, raster-gebaseerde layout.- Flexibele afbeeldingen en media- Mediaquery’s, een module uit de CSS3-specificatie.

Een heel leesbaar en kort boek van de bedenker van de term is Responsive Web Design, door Ethan Marcotte.

Het valt buiten het bestek van dit boek om diep in te gaan op CSS, hoe u browserincom-patibiliteit moet oplossen en hoe u uw pagina zo kunt structureren dat die er zowel op uw 25inch pc-scherm als op uw iPhone goed uitziet. Toch willen we u niet helemaal in de kou laten staan en daarom hebben we een schetsmatige voorbeeldsite gemaakt die er op al deze formaten leesbaar blijft uit zien.

Page 5: 2 Een website bouwen - Welkom bij Pearson Benelux BV

30

PHP EN MYSQL de basis

2.1.2 Standaard opmaak voor een website

Veel websites hebben een structuur waarbij bovenaan een logo, banner, of kopregel staat, Er is een lijst van menuopties, tegenwoordig vaak als tabs bovenin uitgevoerd, ook wel de navigatiebalk genoemd. Daarnaast of daaronder ziet u de werkelijke inhoud van de site. Schematisch ziet het er ongeveer uit als in afbeelding 2.1. De code voor dit voorbeeld is beschikbaar bij de broncode voor dit boek en we zullen er in het vervolg van dit hoofd-stuk belangrijke stukken van laten zien.

Ontwerp

n Er is een topgebied waar meestal een site- of bedrijslogo wordt getoond. n Er is een navigatiebalk waar alle navigatieopties te zien zijn, vaak als tabs bovenin. n Het inhoudsgebied bevat de eigenlijke inhoud van de site, aangepast aan de navigatie-

opties die de gebruiker gekozen heeft in het menugebied. n Soms is er een extra navigatiebalk in de linker kolom van de pagina. n Soms is er extra informatie, zoals nieuwtjes, of een geschiedenis van blog-entries in

een rechter kolom. n Soms is er een smalle strook onderaan de pagina die copyrightinformatie geeft, een

naam, of een websitelink of iets dergelijks.

Afbeelding 2.1Standaard websitestructuur.

Page 6: 2 Een website bouwen - Welkom bij Pearson Benelux BV

31

2 Een website bouwen

Het hierboven geschetste ontwerp is prima voor een pc. Op een iPad in landschapsoriën-tatie ziet het er ook nog goed uit, maar met een iPad in portretmodus of op een smart-phone wordt het allemaal erg klein, we voegen daarom nog een paar regels toe:

Aanvulling ontwerp voor mobiele browserschermen

n Er mogen geen schuifbalken verschijnen voor kleinere schermen. n De tekst moet zich vloeiend voegen in een kleiner scherm, evenals afbeeldingen. n Voor een breedte van 790 pixels (iPad portretmodus) of smaller, worden blokken

tekst niet naast elkaar maar onder elkaar geplaatst. n Voor 480 pixels brede schermen, of smaller, worden de menuopties onder elkaar

geplaatst in plaats van naast elkaar.

Deze regels in aanmerking genomen, ziet onze voorbeeldpagina er op een iPad of een iPhone in portretmodus zo uit:

Afbeelding 2.2Websitestructuur aangepast voor kleine schermen.

Hopelijk is het duidelijk dat de webpagina zich netjes aanpast aan kleine schermen en dat de tekst leesbaar blijft.

Ook zonder tablet of smartphone kunt u dit zelf uitproberen, door het scherm van uw browser kleiner te maken (sleep met uw linker muisknop een van de hoeken). Of, als u in Firefox de gereedschappen voor webontwikkelaars heeft geïnstalleerd, dan is er een optie Resize te zien die het scherm kan vergroten of verkleinen volgens door u op te geven afmetingen.

Page 7: 2 Een website bouwen - Welkom bij Pearson Benelux BV

32

PHP EN MYSQL de basis

We gaan in de volgende paragraaf iets dieper in op de bijbehorende HTML en CSS van deze pagina.

2.2 Een zichzelf aanpassende webpagina met CSS3Het nu volgende voorbeeld kunt u vinden in debasis/bonushoofdstuk02/responsive-vb.

We beginnen met de HTML-code van de pagina waarvan u al afbeeldingen hebt gezien (2.1 en 2.2):

lampjes.html

C <!DOCTYPE html><html> <head> <meta charset="utf-8"> <meta content="width=device-width, initial-scale=1.0" name="viewport"> <title>Weblampjes</title> <link href="lampjesx.css" rel="stylesheet" type="text/css" /> </head> <body> <div id="page"> <div class="container section"> <div class="headsection"> <h1 class="pagehead">Weblampjes!</h1> <ul class="nav"> <li><a href="#">Home</a></li> <li>. . .</li> </ul> </div> <div class="main"> <div class="article"> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. . . . </p> </div><!-- /end .article --> </div><!-- /end .main --> <div class="other"> <div class="entries"> <p> In molestie magna . . . </p>

Page 8: 2 Een website bouwen - Welkom bij Pearson Benelux BV

33

2 Een website bouwen

</div> <!-- /end .entries --> </div><!-- /end .other --> <div id="footer"> <h4>Voettekst</h4> </div> </div><!-- /end .container.section --> </div><!-- /end #page --> </body></html>

Misschien zou het mogelijk zijn geweest met iets minder div-tags toe te kunnen, maar zoals het nu is, kunt u de pagina flexibeler uitbreiden met afbeeldingen of video of met andere soorten tekst. Later gaan we de HTML veranderen in een PHP-template, zodat we er onze eigen inhoud in kunnen zetten.

Zelfs als we geen CSS toepassen, dan blijft de tekst leesbaar en de links bruikbaar, want dan ziet het scherm er zo uit:

Weblampjes!Home ... Contact Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sem enim, dignissim vitae lobortis nec, condimentum . . . mi nibh porta velit, quis viverra libero dui et lorem. Vestibulum urna neque, congue nec cursus et, venenatis ut ligula. In molestie magna nec dui elementum quis tempor lectus malesuada. Integer aliquam quam eget sapien eleifend non tristique mauris euismod. Voettekst

2.2.1 Vloeiende rasteropmaak met CSS

Zoals gezegd, gaan we gebruikmaken van vloeiende rasteropmaak met behulp van CSS3 mediaquery’s.

Page 9: 2 Een website bouwen - Welkom bij Pearson Benelux BV

34

PHP EN MYSQL de basis

vLoEiENDE R a S T ERoPMa ak

Vloeiende rasteropmaak (Engels: fluid grid layout) is een principe waar het ontwerp van een web-site op een raster wordt gelegd en in kolommen opgedeeld. Door de opmaak in percentages in plaats van pixelwaarden te definiëren kan het ontwerp vloeiend schalen bij wisselende scherm-grootte. Een handig stukje gereedschap voor het berekenen van de percentages is hier te vinden: www.tinyfluidgrid.com.

Een belangrijke HTML-instructie om op een mobiel apparaat een vloeiend raster te kun-nen laten zien vindt u in de head-sectie van het document:

C <meta content="width=device-width, initial-scale=1.0" name="viewport">

Deze instructie zegt dat de browser als breedte van het scherm de breedte van het apparaat moet nemen. Dat klinkt als het intrappen van een open deur, maar dat is het blijkbaar niet, want veel mobiele browsers doen net of het scherm veel breder is, zodat u moet schuiven om alles te zien te krijgen. Er zijn dan weliswaar geen schuifbalken, maar het kan mooier als de site zich vloeiend aanpast.

Om geen last te hebben van browserverschillen in standaard opmaak voegen we in onze CSS-code een paar lange regels toe die voor een hele reeks elementen de margin, pad-ding en border op 0 zetten en nog een paar dingen. Deze CSS code is hier te verkrijgen: http://meyerweb.com/eric/tools/css/reset/.

We laten eerst een stukje CSS zien uit lampjes.css dat de afmetingen voor een groter scherm definieert:

C /* #page is eerst fixed om de pagina niet te breed * te laten worden op een breed scherm */#page { margin: 1em auto; width: 960px;}.container { margin: 0 auto 3em; width: 93.75%; /* 900px / 960px */}.container .main { float: left; width: 62.8888889%; /* 566px / 900px */}.container .other { float: right; width: 36.6666667%; /* 330px / 900px */

Page 10: 2 Een website bouwen - Welkom bij Pearson Benelux BV

35

2 Een website bouwen

height: 100%;}

Zo als u ziet komt er nergens een vaste pixelwaarde voor, met uitzondering van de oor-spronkelijke paginabreedte. Alles is gedefinieerd via percentages van de breedte van het omvattende blok. Verder zijn kantlijn- en opvulwaarden (margin en padding) uitgedrukt in em, waarbij 1em de grootte is van het huidige lettertype. Dat betekent dat mobiele browsers, die een kleiner lettertype gebruiken, automatisch ook kleinere kantlijnen en lettergroottes zullen gebruiken. De merkwaardige percentages zijn ontstaan door het pa-ginaontwerp in kolommen in te delen en er dan berekeningen op toe te passen. Ik moet bekennen dat ik er uit luiheid wat mee heb gesjoemeld, dus misschien klopt het niet allemaal precies. Meer details over vloeiende rasters kunt u hier lezen: www.alistapart.com/articles/fluidgrids/.

2.2.2 CSS3 mediaquery’s

We hebben nu de basis gelegd voor een vloeiend raster, maar als onze pagina op een smartphonescherm wordt getoond, dan is een 2- of 3-kolomsopmaak niet erg prettig om te lezen. We willen in dat geval dat alle kolommen onder elkaar worden getoond.

Via een CSS3 mediaquery weet de browser dat het de opmaak moet aanpassen aan de kleinere schermbreedte. Bijvoorbeeld, als de pagina smaller wordt dan 960 pixels in onze voorbeeldpagina lampjes.html, dan willen we ook aan de paginabreedte een percen-tage toekennen. Dat ziet er zo uit:

C @media screen and (max-width: 960px) { #page { width: 90%; }}

Mocht het scherm nog smaller worden, voor tablet pc’s in portretmodus bijvoorbeeld, dan kunnen we de kolommen onder elkaar zetten:

C @media screen and (max-width: 790px) { /* .main, .container, .other, #footer { border: 0; } */ .container .main { width: auto; float: none; } .container .other {

Page 11: 2 Een website bouwen - Welkom bij Pearson Benelux BV

36

PHP EN MYSQL de basis

width: auto; float: none; }}

Voor smartphones, zowel in portret- als in landschapstand, maken we nog een verdere aanpassing:

C @media screen and (max-width: 480px) { .nav { margin: -0.9em -0.7em 0 0; font-size: 1em; } .nav li { display: block; border-bottom: 1px solid white; }}

Behalve de kolommen, zijn nu ook de menuopties onder elkaar in plaats van naast elkaar gezet.

De belangrijkste aspecten van dit stijlblad hebben we nu behandeld. We willen het re-sultaat van onze noeste arbeid natuurlijk voor onze echte sites gaan gebruiken, daarom gaan we ons in de volgende paragraaf richten op het maken van een template op basis van het bestand lampjes.html en het stijlblad lampjes.css. We gaan ook het geheel in een MVC-structuur plaatsen. We maken ons template door een proces van refactoring, zodat het eerste resultaat er net zo uit zal zien als het voorbeeld in afbeelding 2.1, maar dan opgebouwd via templates.

2.3 Een websitespecifiek raamwerkIn het boek hebt u reeds kennisgemaakt met het raamwerkje fw. Hierin zijn een aantal zaken opgenomen die algemeen toepasbaar zijn bij het bouwen van websites. Het is verleidelijk om hier een aantal dingen aan toe te voegen die we graag zouden willen hergebruiken bij het bouwen van verschillende pagina’s van onze site of van verschil-lende sites met een vergelijkbare structuur. Uiteindelijk hebben we na enig heen en weer geschuif hier niet voor gekozen en we hebben besloten om een sitespecifiek, of zo u wilt, een domeinspecifiek raamwerk te maken.

Page 12: 2 Een website bouwen - Welkom bij Pearson Benelux BV

37

2 Een website bouwen

2.3.1 Inhoud van een sitespecifiek raamwerk

In hoofdstuk 10 hebben we de map waar ons raamwerkje fw in stond als sub-map van de map hoofdstuk10 geplaatst. Het is niet handig om dit voor elk hoofdstuk opnieuw te moeten doen, daarom gaan we het raamwerk fw meteen in de map debasis plaatsen.

iNcLuDE PaDEN

Door deze verhuizing moet u ook config.inc aanpassen, anders werkt het automatisch laden van klassen niet meer. Misschien zou het beter zijn paden toe te voegen in een .htaccess-be-stand voor Apache, maar dat maakt het uploaden naar uw site bij een webhoster weer ingewik-kelder. Voor een prototype is onze aanpak voldoende.

We nemen de volgende stappen: n Kopieer de map fw met ons privéraamwerkje naar de map debasis. n Kopieer config.inc naar de map bonushoofdstuk02 en pas de inhoud aan door de

volgende twee regels aan het begin te plaatsen:

C $docRoot = "../"; set_include_path($docRoot.PATH_SEPARATOR.get_include_path());

n Hiermee passen we het pad aan waar PHP gaat zoeken naar de opgegeven bestands-namen en daar maakt de autoloader voor klassen weer gebruik van.

n Maak een mappenstructuur voor het sitespecifieke raamwerk, als volgt:

C debasis –- wl (het domein-specifieke raamwerk weblampjes) -- site (het site-specifieke gedeelte) -- table (een gedeelte voor tabel-specifieke klassen)

n Deze mappenstructuur met de top map wl (afkorting van weblampjes), lijkt op de mappenstructuur voor fw, maar er is een extra onderverdeling in twee mappen: site en table. De map site is er voor site gerelateerde zaken en in de map table gaan we straks klassen neerzetten die specifiek voor het afhandelen van query’s op een bepaalde tabel of groep van tabellen zijn.

n U voelt al aankomen dat het sitegerelateerde raamwerk wl gaat heten, een afkorting van Weblampjes.

n Het raamwerk fw passen we iets aan door er een map form aan toe te voegen, waar straks formulier-gerelateerde klassen komen te staan. De structuur is nu zo:

Page 13: 2 Een website bouwen - Welkom bij Pearson Benelux BV

38

PHP EN MYSQL de basis

C debasis –- fw -- db (algemene databaseklassen) -- form (formulier-gerelateerde klassen) -- tmpl (template-gerelateerde klassen)

MaPPENS T Ruc T uuR vooR DE R a aMwERkEN

Het is uw goed recht om het niet eens te zijn met onze mappenstructuur. We hebben een aantal keren heen en weer geschoven met de verschillende bestanden en ook onze naamgevingscon-ventie hebben we een aantal keren gewijzigd voordat het in het boek terecht kwam zoals het nu is. We hopen dat u mee wil denken met deze structuur, omdat dit het terugvinden van bestanden en het begrijpen van de opbouw van onze site vergemakkelijkt.

De template fluidgrid en aanverwante bestanden moeten onderdeel gaan uitmaken van wl, omdat we het template wel graag willen kunnen hergebruiken maar het naar onze mening te sitespecifiek is voor het raamwerk fw. Daarom maken we een submap fluid-grid voor de map site die als basis dient voor alle verdere bestanden in deze compo-nent.

Binnen deze map fluidgrid gaan we onze MVC-structuur realiseren, maar voorlopig is er alleen een view, die uit de mappen css, tmpl en view bestaat. In de map css komen de stijlbladen, in de map tmpl komt een speciale template-klasse voor het template fluid-grid en in de map view komen de templates. Kijk naar afbeelding 2.3 om onze uitbreiding van de structuur te zien:

Afbeelding 2.3 Structuur voor fluidgrid component

De bestanden binnen de mappenstructuur onder de map fluidgrid vormen de compo-nent fluidgrid voor de site weblampjes. We hebben standaard naamgeving toegepast, dus er is een map view, waarin de hoofdtemplate index.inc heet. Verder is er een map css. Hoewel de stijlbladen eigenlijk bij de view horen, zetten we ze voor de duidelijkheid toch maar apart. Het hoofd stijlblad heet style.css.

Page 14: 2 Een website bouwen - Welkom bij Pearson Benelux BV

39

2 Een website bouwen

Dit zijn onze volgende stappen in het proces van het maken van de component fluid-grid:

n We maken een speciale klasse FluidGridTemplate, die een aantal standaardwaarden voor het hoofdtemplate voor de component fluidgrid maakt. We zullen zo zien hoe deze klasse eruit ziet.

n We plaatsen in de map view het bestand lampjes.html en hernoemen het naar in-dex.inc. We gaan hierna dit bestand bewerken tot een template.

n Plaats het bestand lampjes.css in de map css, en hernoem het naar style.css.

2.3.2 Het template fluidgrid.inc en de klasse FluidGridTemplate

We maken vervolgens een template van index.inc in wl/site/fluidgrid/view door alle tekst die geen HTML is eruit te strippen en te vervangen door een PHP-statement van de vorm:

<?=$myvar?>, zoals we al eerder gezien hebben en wat een verkorte schrijfwijze is voor: <?php echo $myvar;?>. Het template ziet er dan zo uit:

C <!DOCTYPE html><html> <head> <meta content="width=device-width, initial-scale=1.0" name="viewport"> <title>Weblampjes</title> <link href="<?=$style?>" rel="stylesheet" type="text/css" /> <?=$links?> </head> <body> <div id="page"> <div class="container section"> <div class="headsection"> <h1 class="pagehead"><?=$pagehead?></h1> <?=$menu?> </div> <div class="main"> <div class="article"> <?=$article?> </div><!-- /end .article --> </div><!-- /end .main --> <div class="other"> <div class="entries"> <?=$entries?> </div> <!-- /end .entries --> </div><!-- /end .other --> <div id="footer">

Page 15: 2 Een website bouwen - Welkom bij Pearson Benelux BV

40

PHP EN MYSQL de basis

<h4><?=$footer?></h4> </div> </div><!-- /end .container.section --> </div><!-- /end #page --> </body></html>

Dit zal u ongetwijfeld bekend voorkomen, vergelijk deze code maar met lampjes.html.

Als u deze template probeert te gebruiken zoals we dat in het vorige hoofdstuk hebben geleerd, dan zult u vooral veel foutboodschappen op uw scherm zien verschijnen over variabelen die niet gedefinieerd zijn, zoiets als deze:

Notice: Undefined variable: menu in C:\xampp\htdocs\debasis\bonushoofdstuk02\cntrl_fluidgrid.php on line 5

Bij het ontwikkelproces is dat nogal onhandig en bovendien wilt u misschien sommige waarden leeg kunnen laten, zonder dat u dit expliciet moet opgeven. Daarom hebben we een klasse gemaakt, die een sub-klasse van de klasse Template is en die specifiek alles af weet van het fluidgrid.inc template: FluidGridTemplate.

Hier is de PHP-code voor de klasse FluidGridTemplate, die we hebben geplaatst in wl/site/fluidgrid/tmpl:

C <?php/* FluidGridTemplate is een subklasse van Template om de specifieke * fluid grid template van standaardwaarden te voorzien. * */

namespace wl\site\fluidgrid\tmpl;

class FluidGridTemplate extends \fw\tmpl\Template { public function __construct($file = null) { parent::__construct('wl/site/fluidgrid/view/index.inc'); // zet standaard waarden $this->set('style', '../wl/site/fluidgrid/css/style.css'); $this->set('headsection', ''); $this->set('menu',''); $this->set('pagehead','Geen waarde voor $pagehead opgegeven!'); $this->set('article',''); $this->set('entries',''); $this->set('footer',''); }}?>

Page 16: 2 Een website bouwen - Welkom bij Pearson Benelux BV

41

2 Een website bouwen

We maken een aantal opmerkingen over de code van deze klasse: n De klasse hoort bij de namespace wl\site\fluidgrid\tmpl, zodat de autoloader

hem kan terugvinden. n We hebben parent::__construct('wl/site/fluidgrid/view/index.inc'); als

eerste regel in de __construct()-methode opgenomen. Deze regel zorgt ervoor dat de __construct()-methode in de superklasse van FluidGridTemplate (dat is Template), wordt uitgevoerd, met als parameter de naam van onze vloeiend raster template.

n De __construct()-methode in de klasse Template doet niets anders dan de naam van het bestand onthouden in een property, zodat bij de aanroep van de fetch() me-thode dit template bestand ingevoegd kan worden. Kijk eventueel terug naar de code van de klasse Template in paragraaf 10.4.3.

n Daarna geven we standaardwaarden aan alle variabelen die in de template gebruikt worden, zodat nadat deze klasse is gemaakt, u met uw eigen waarden deze waarden weer kunt overschrijven, maar als u dat niet doet dan komt er meestal een lege string te staan.

n Let ook op de variabelen style en extra-style, dit zijn verwijzingen naar stijlbla-den, waarvan de eerste het standaard stijlblad is dat we in de vorige paraaf, 2.3.1 en 12.1.3 hebben besproken. Het extra stijlblad is bedoeld om stijlinformatie te kunnen aanpassen zonder het standaard stijlblad te moeten veranderen, wat niet leuk zou zijn voor andere gebruikers van dit template. Het extra stijlblad is standaard een leeg bestand, maar door de waarde naar uw eigen bestand te laten wijzen is dit flexibel aan te passen.

We kunnen nu een controller script (cntrl_fluidgrid.php, in de hoofdmap bonus-hoofdstuk02) maken dat er zo uitziet:

C <?phpinclude ('config.inc');$tpl = new \fw\tmpl\FluidGridTemplate();echo $tpl->fetch();?>

Als u dit script uitvoert, dan ziet u:

Afbeelding 2.4Template zonder inhoud.

Page 17: 2 Een website bouwen - Welkom bij Pearson Benelux BV

42

PHP EN MYSQL de basis

Dit is het raamwerk van waaruit we webpagina’s kunnen maken volgens ons vloeiend rasterontwerp. Als voorbeeld gaan we de pagina vullen met de tekst die we er net had-den uitgesloopt.

2.3.3 Voeg inhoud toe met het fluidgrid.inc template

Om de pagina er weer zo uit te laten zien als in afbeelding 2.1 of gevuld met andere in-houd, moeten we de variabelen in de template onze eigen waarden geven.

Het voorbeeld dat we maken hoort niet bij een van de twee raamwerken, het maakt er alleen gebruik van. We moeten het voorbeeld dus ergens anders opslaan, bijvoorbeeld in debasis/bonushoofdstuk02/fluidgrid-vb. Maak ook de volgende submappen: debasis/bonushoofdstuk02/fluidgrid-vb/css en debasis/bonushoofdstuk02/fluidgrid-vb/view.

We kunnen ons voorstellen dat het nog niet helemaal duidelijk is wat u moet doen. Kijk eens naar afbeelding 2.5, daarin staat schematisch aangegeven welke variabelen in de template gebruikt worden en waar ze terechtkomen:

Voor ieder van de variabelen $headsection, $pagehead, $menu, $article, $entries en $footer moet u een waarde aanmaken die via de set()-methode van de klasse tem-plate aan het template beschikbaar wordt gesteld. Deze waarde kan een tekststring zijn maar ook een template, zodat u een nest van templates kunt opbouwen.

Laten we beginnen met het menu. Plaats een bestand met de naam menu.inc in de map en geef het de volgende inhoud:

Afbeelding 2.5 Schema van het template fluidgrid

Page 18: 2 Een website bouwen - Welkom bij Pearson Benelux BV

43

2 Een website bouwen

C <ul class="nav"> <li><a href="#">Home</a></li> <li><a href="#">Optie 1</a></li> <li><a href="#">Optie 2</a></li> <li><a href="#">Over ons</a></li> <li><a href="#">Contact</a></li></ul>

We hebben de tekst ten opzichte van het menu in de vorige versie iets veranderd, zodat u een verschil kunt zien.

Verder willen we de kleur van de menu-items veranderen en daarvoor maken we een stijlblad met de naam style.css dat we in fluidgrid-vb/css plaatsen en dat deze CSS-instructies heeft:

C .nav li { background-color: blue;}

.nav a:link, .nav a:visited { color: #FFFFFF;}

De bedoeling is dat de menu-items blauw worden, maar omdat de tekst dan slecht te le-zen is, maken we die wit. Nu moeten we ons controllerscript cntrl_fluidgrid.php nog aanpassen om gebruik te maken van het nieuwe menu:

C <?phpinclude ('config.inc');

$tpl = new \fw\tmpl\FluidGridTemplate();

$head = new \fw\tmpl\Template('fluidgrid-vb/view/headsection.inc');$tpl->set('headsection', $head);

// maak een menu template$menu = new \fw\tmpl\Template('fluidgrid-vb/view/menu.inc');$tpl->set('menu', $menu);echo $tpl->fetch();?>

U ziet: n Het menu is een template, die we kunnen verwerken met de gewone klasse Template. n We hebben de variabele $headsection laten verwijzen naar een template, fluid-grid-vb/view/headsection.inc, dat het extra stijlblad dat we zojuist gemaakt heb-ben invoegt in de HTML head-sectie van het resulterende HTML-bestand.

Page 19: 2 Een website bouwen - Welkom bij Pearson Benelux BV

44

PHP EN MYSQL de basis

n Voer het script cntrl_fluidgrid.php uit en als het goed is ziet u nu de pagina zoals in afbeelding 2.4 met de menuopties toegevoegd in een blauwe kleur.

T iP vooR HE T T ES T EN oP EEN SMaR T PHoNE

Begin met het IP-adres van uw pc op te zoeken. Op een Windows-machine kunt u dit doen door een command window te openen: ga naar het startmenu en tik cmd in het teksvak “programma’s zoeken”. Typ daarin ipconfig. Dan ziet u ergens een regel met IPv4-adres. Dat adres, zoiets als 192.168.178.13, gebruikt u in de adresbalk van de browser op uw smartphone (of tablet) in plaats van localhost. Als het goed is ziet u dan uw pagina op uw smartphone of tablet.

oEfENiNg 2 .1 Maak de pagina weer compleet

Het is nuttig om goed te zien hoe het template fluidgrid in elkaar zit. U kunt het vinden in wl/site/fluidgrid/view/index.inc. Kijk ook naar afbeelding 2.5 voor een schematisch overzicht, om te zien hoe u er eigen tekst of verdere templates aan kunt toevoegen.

We laten u als oefening de pagina verder aanvullen zodat hij eruit ziet als afbeelding 2.1.

Pas het controllerscript cntrl_fluidgrid.php aan door alle in het fluidgrid-template gebruikte variabelen een waarde te geven. Maak nieuwe templates waar nodig. U kunt de “Lorem ipsum’ tekst gebruiken zoals wij dat ook gedaan hebben, maar u kunt natuurlijk ook uw eigen tekst verzinnen, als een begin voor uw eigen webpagina.

Probeer het resultaat te tonen op uw smartphone als u er een hebt.

Na dit verhaal over hoe u een website kunt bouwen die volgens MVC-principes gestructu-reerd is en die aanpasbaar is voor kleine schermen, zoals die op smartphones te vinden zijn, gaan we verder met een paar inhoudelijke zaken.

2.4 Een authenticatie- en autorisatiemoduleDit deel van het hoofdstuk over website bouwen gaat over het controleren en beperken van toegang tot uw website of delen daarvan. Dat is niet hetzelfde als het beveiligen van uw site tegen hackers of dieven die financiële gegevens willen stelen. Een discussie daar-over hebben we al eerder gevoerd.

Een voorbeeld is het regelen van de toegang tot een fotoalbum op uw site, of een weblog. Misschien wilt u wel familie en goede kennissen uw foto’s en schrijfsels laten zien, maar om de hele wereld mee te laten genieten vindt u waarschijnlijk te veel van het goede. We gaan daarom nuttig gebruikmaken van een database voor het bewaren en beheren

Page 20: 2 Een website bouwen - Welkom bij Pearson Benelux BV

45

2 Een website bouwen

van gebruikersgegevens. We laten zien hoe u de toegang tot een pagina kunt regelen met autorisaties en hoe u voor iedere gebruiker de gebruikersnaam en het wachtwoord in een tabel kunt opslaan.

n Authenticatie is het proces van verifiëren of u bent wie u zegt te zijn, meestal met behulp van een gebruikersnaam/wachtwoord.

n Autorisatie bepaalt welke gedeelten van de website u mag zien en welke taken u mag uitvoeren.

2.4.1 Mogelijkheden voor authenticatie en autorisatie

Natuurlijk zijn er meerdere manieren om authenticatie en autorisatie te verzorgen. Een populaire methode is bijvoorbeeld om een hele map te beveiligen met behulp van de Apache-webserver. (Zie hiervoor http://httpd.apache.org/docs/2.0/howto/auth.html.) Deze methode is echter niet erg flexibel. Het is bijvoorbeeld moeilijk om onderscheid te maken tussen verschillende soorten gebruikers en de rollen die zij vervullen bij het benaderen van een website.

LoREM iP SuM

Dit is een standaard tekst zonder betekenis die eruit ziet als Latijn. Deze tekst is handig om te gebruiken bij het ontwerpen van webpagina’s of presentaties omdat het neutrale tekst is die toch een indruk geeft hoe de tekst er uit zal zien. U kunt er alles over lezen op deze pagina: http://nl.lipsum.com/ .

Waar onachtzaam gebruik van de tekst toe kan leiden ziet u in afbeelding 2.6

Afbeelding 2.6Klein museum in Californië met uitleg over geïmporteerde planten, bijna helemaal met Lorem Ipsum tekst!

Page 21: 2 Een website bouwen - Welkom bij Pearson Benelux BV

46

PHP EN MYSQL de basis

Een andere mogelijkheid die door beginnende websitebouwers vaak wordt overwogen is om wachtwoorden in een bestand op te slaan, of nog erger, in het script zelf. U zult begrij-pen dat dit laatste heel slecht onderhoudbaar is, en het opslaan in bestanden is minder veilig dan opslaan in een database.

Veel ontwikkelaars van webtoepassingen kiezen ervoor om zelf gebruikersnamen in een database op te slaan, met hun wachtwoorden. Daarbij kunt u ook voor iedere gebruiker aangeven welke rol die gebruiker kan vervullen: een beheerder zal bijvoorbeeld dingen mogen veranderen, terwijl een eindgebruiker alleen maar mag kijken.

Tamelijk nieuw is de mogelijkheid om de authenticatie van uw gebruikers te laten verzorgen door Facebook of Twitter. Dit maakt het eenvoudig voor een ontwikkelaar om authenticatie voor een site te verzorgen en voor de gebruiker omdat die niet 127 wacht-woorden hoeft te onthouden. Persoonlijk wordt ik meestal tegengehouden door het pop-up-je dat vraagt of ik mijn Facebook- of Twitter-gegevens wil delen met de webtoe-passing, maar als ik dan weer eens een vergeten wachtwoord in leesbare tekst krijg toe-gestuurd, of als er weer nieuws is over op straat liggende klantgegevens, dan vraag ik me af of ik liever door de spreekwoordelijke kat of door de hond gebeten wil worden. Meer informatie over authenticatie via Twitter kunt u hier vinden: https://dev.twitter.com/docs en over Facebook hier: http://developers.facebook.com/docs/guides/web/.

Wij kiezen hier voor het opslaan van onze eigen authenticatie- en autorisatiegegevens, voornamelijk omdat het ons de mogelijkheid biedt een overzichtelijke, database-gere-lateerde component aan onze website toe te voegen. We geven de component de naam login-module.

2.4.2 Ontwerp voor een loginmodule

We maken een traditionele loginmodule, waarbij u een formulier te zien krijgt waarin u uw gebruikersnaam (we gebruiken hiervoor uw e-mail adres) en wachtwoord kunt intypen. Na controle in de database krijgt u toegang tot afgeschermde onderdelen van de site, als uw wachtwoord in orde is bevonden.

We onthouden dat u bent ingelogd en wie u bent in PHP-sessie variabelen, $_SESSION. Om dat te kunnen doen starten we een sessie, zoals uitgelegd in hoofdstuk 11.

Een loginmodule is vrij algemeen toepasbaar, maar de tabellen die we gaan maken horen bij de site. Daarom plaatsen we de loginmodule in het raamwerk wl.

We geven hier een aantal punten waaraan de loginmodule moet voldoen. n Voor iedere pagina van een site is er de mogelijkheid te bepalen wie er toegang heeft

tot deze pagina. n Autorisaties worden beschreven aan de hand van de rol die een gebruiker heeft bij het

bezoeken van de site. n Voorbeelden van rolnamen zijn: advanced, level3, adult, family, et cetera.

Page 22: 2 Een website bouwen - Welkom bij Pearson Benelux BV

47

2 Een website bouwen

n Voor de authenticatie van iedere gebruiker worden gebruikersnaam en wachtwoord opgeslagen in een database.

2.4.3 Tabellen voor de loginmodule

We beginnen met het aanmaken van twee tabellen, een voor de gebruikersnamen en wachtwoorden, en een voor de rollen die iedere gebruiker kan vervullen, zoals adminis-trator, bezoeker, redacteur, enzovoorts.

Dit is de definitie van een webuser-tabel, die de volgende kolommen zal hebben: n id – Een AUTO_INCREMENT nummer, tevens primaire sleutel. n email – Het e-mailadres van de gebruiker doet ook dienst als gebruikersnaam.

E-mailadressen moeten uniek zijn. Dit kunt u afdwingen door een unieke index te ma-ken. Het voordeel van zowel een id als een email ter identificatie van een gebruiker is dat u eventueel het e-mailadres kunt veranderen zonder in problemen te komen met andere tabellen die naar deze gebruiker verwijzen. Ook is een id-verwijzing korter dan een email-verwijzing, dat scheelt ruimte en tijd.

n naam – De volledige naam van de gebruiker. Om het niet te ingewikkeld te maken gaan we geen aparte kolommen definiëren voor voornaam, tussenvoegsel, achternaam enzovoorts. U kunt altijd naderhand een extra tabel maken, met bijvoorbeeld ook adresgegevens, waar dit wel in staat en die verwijst naar de tabel webuser.

n wachtwoord – Dit spreekt voor zich. Het wachtwoordveld moet een lengte van 32 hebben om de MD5-encryptie van het wachtwoord te kunnen opslaan. We gaan de wachtwoorden versleutelen met de zogenoemde MD5-functie, die zowel in MySQL als in PHP beschikbaar is. U dacht toch niet dat we het wachtwoord zelf zouden opslaan? Trouwens, als u financiële gegevens zou willen kunnen opslaan in uw database, dan is encryptie met de MD5-functie niet voldoende, omdat met nieuwe decryptie technie-ken de wachtwoorden te achterhalen zijn als de dief de versleutelde wachtwoorden heeft kunnen achterhalen. Dat kost wel tijd. De vraag is equivalent met hoe zware sloten u op uw huis moet plaatsen. Een inbreker komt altijd binnen, maar met zware sloten duurt het langer. Voor onze website is MD5 genoeg.

n status – Dit is een veld waarin we allerlei dingen kunnen vastleggen, zoals een gebruiker die zijn/haar wachtwoord opnieuw moet instellen omdat er een tijdelijk wachtwoord is opgestuurd, of een gebruiker die op een zwarte lijst is komen te staan.

n registratiedatum – De datum van registratie.

De SQL die nodig is om de tabel webuser te maken is als volgt:

C CREATE TABLE weblampjes.webuser ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY , email VARCHAR( 100 ) NOT NULL , naam VARCHAR( 100 ) NOT NULL , wachtwoord CHAR( 32 ) NOT NULL , status CHAR( 3 ) NOT NULL , registratiedatum TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,

Page 23: 2 Een website bouwen - Welkom bij Pearson Benelux BV

48

PHP EN MYSQL de basis

UNIQUE (email)) ENGINE = InnoDB

oEfENiNg 2 .2 Maak de tabel webuser

Start XAMPP op en phpMyAdmin. Maak de tabel webuser volgens bovenstaande specificatie. U kunt of de SQL hierboven in een SQL-tekstinvoerveld plakken, of via de phpMyAdmin-invulformulieren de tabel definiëren. Voeg de tabel toe in de database weblampjes.

Vervolgens richten we onze blik op de tabeldefinitie voor userauth. De kolommen zijn: n userid – Een getal dat verwijst naar de id van de gebruiker in de tabel webuser. n autorisatie – De rol die deze gebruiker mag hebben voor deze webtoepassing. n Dit levert de volgende SQL op:

C CREATE TABLE weblampjes.userauth ( userid INT NOT NULL , autorisatie VARCHAR( 30 ) NOT NULL) ENGINE = InnoDB;

ENgELS of NEDERL aNDS ?

Het is steeds moeilijk om een keuze te maken tussen Engelse of Nederlandse namen. Engels is beter als u bij de ontwikkeling van de toepassing ook wereldwijd wil kunnen samenwerken. Voor dit boek willen we zoveel mogelijk Nederlands gebruiken, maar we zijn daar niet overal in geslaagd, soms omdat we het gewoon geen mooie naam vonden, vandaar de namen webuser en userauth, wat eigenlijk webgebruiker en gebruikersautorisatie had moeten zijn.

oEfENiNg 2 .3 Maak de tabel userauth

Maak de tabel userauth volgens de instructies van oefening 2.2.

Het is mogelijk om af te dwingen dat er voor de userid in de tabel userauth ook een bijbehorende rij in de tabel webuser gevonden kan worden, bijvoorbeeld door deze SQL uit te voeren:

C ALTER TABLE userauth ADD FOREIGN KEY (userid) REFERENCES webuser(id) ON DELETE CASCADE ON UPDATE RESTRICT

Page 24: 2 Een website bouwen - Welkom bij Pearson Benelux BV

49

2 Een website bouwen

Een foreign key, of vreemde sleutel, geeft een verwijzing naar een kolom die unieke sleu-tels bevat in een andere tabel. De ON DELETE CASCADE ON UPDATE RESTRICT betekent dat als er een rij in webuser wordt verwijderd, de bijbehorende rijen in userauth ook worden verwijderd en dat als u de userid in userauth verandert, er wel een bijbehoren-de waarde in webuser moet zijn, en dat u de id in webuser niet kunt wijzigen.

Eigenlijk zouden we nog een derde tabel moeten maken met mogelijke autorisaties voor gebruikers erin, waaraan vanuit userauth gerefereerd kan worden. Met een tweede vreemde sleutel op de tabel userauth zou het dan onmogelijk zijn om iemand niet-be-staande autorisaties toe te wijzen.

Voorbeeldgegevens

Om niet meteen scripts te hoeven maken om nieuwe gebruikers of autorisaties te kunnen invoeren hebben we via phpMyAdmin vast een paar rijen in de twee tabellen gezet.

De volgende tabel geeft de gegevens weer die we in de tabel webuser hebben staan:

iD EMaiL Na aM wacH T wooRD S TaT uS REg iS T R aT iE-DaT uM

1 [email protected] Piet Dieallesziet 81dc9bdb52d-04dc20036db-d8313ed055

2012-01-17 14:50:35

2 [email protected] Truus Excuus 674f3c2c1a8a6f90461e-8a66fb5550ba

2012-01-17 14:50:35

3 [email protected] Marie Magniets e2fc714c4727ee9395f-324cd2e7f331f

2012-01-17 14:53:29

We slaan de wachtwoorden op nadat we de MD5-functie erop hebben losgelaten. Dat betekent dat we iemand die zijn of haar wachtwoord heeft vergeten, alleen een nieuw wachtwoord kunnen toesturen, omdat we vanuit de database het oude wachtwoord niet kunnen achterhalen.

Om te testen is het handig om de niet-versleutelde wachtwoorden te weten:

Na aM wacH T wooRD Piet Dieallesziet 1234Truus Excuus 5678Marie Magniets abcd

Page 25: 2 Een website bouwen - Welkom bij Pearson Benelux BV

50

PHP EN MYSQL de basis

Hier zijn de gegevens in de tabel userauth:

uSERiD au T oRiSaT iE 1 expert1 professioneel2 expert

De gegevens in de tabel userauth zijn een beetje onbegrijpelijk omdat we misschien niet zo gauw kunnen bedenken wie userid 1 nu eigenlijk is, zeker als we niet drie, maar een paar duizend gebruikers hebben. We kunnen dat voor onszelf beter zichtbaar maken door de volgende query uit te voeren:

C SELECT naam, autorisatie FROM webuser, userauth WHERE webuser.id = userauth.userid

Uitgevoerd in phpMyAdmin krijgen we het volgende resultaat:

Na aM au T oRiSaT iE Piet Dieallesziet expertPiet Dieallesziet professioneelTruus Excuus expert

In ons voorbeeld kan Piet blijkbaar twee rollen hebben en Marie komt bij de rollen niet voor. We hebben ervoor gekozen om geen hiërarchie van rollen te maken, zoals in het bekende contentmanagementsysteem Joomla, waar een administrateur alles mag wat een redacteur mag en meer. Een redacteur mag weer alles wat een geregistreerde gebrui-ker mag en meer. Omdat het best zo kan zijn dat een administrateur geen artikelen mag bijwerken, maar een redacteur geen artikelen mag verwijderen bijvoorbeeld. Dat is niet met een hiërarchie uit te drukken.

oEfENiNg 2 . 4 Maak queries over gebruikersgegevens

Verzin query’s om alle autorisaties van Piet weer te geven en om te zien wie er ‘expert’-autorisatie bezit.

2.4.4 Het inlogformulier

Behalve de tabellen hebben we een formulier nodig waarmee de gebruiker zijn gegevens kan opsturen zodat hij of zij ingelogd kan worden. We gaan voortbouwen op het werk dat

Page 26: 2 Een website bouwen - Welkom bij Pearson Benelux BV

51

2 Een website bouwen

we in hoofdstuk 7 gedaan hebben en we houden ons aan de MVC structuur die we eerder in dit hoofdstuk hebben toegepast. Later zullen we het inlogformulier in ons vloeiende rastervoorbeeld inbouwen, voor nu maken we eerst een testpagina.

Zoals we aan het begin van paragraaf 2.4.2 hebben betoogd, is een loginmodule van groter belang dan alleen voor de startpagina van onze eigen webtoepassing. Daarom hebben we de module in het raamwerk wl geplaatst. We plaatsen hem niet in fw, omdat de implementatie van de functionaliteit voor verschillende sites zodanig kan verschillen dat het moeilijk is er een generalisatie voor te vinden. Onderstaand schema in afbeelding 2.7 laat de structuur zien en de nieuwe bestanden die we hebben gemaakt.

We merken op:

1 De module login staat naast de module fluidgrid. Hierdoor kunt u ze onafhankelijk van elkaar gebruiken, beheren of vervangen.

2 Standaard bestanden met standaard namen zijn wl/site/login/css/style.css en wl/site/login/view/index.inc.

3 In het bestand index.inc staat de code voor een formulier dat u heel erg bekend zal voorkomen als u hoofdstuk 7 gelezen hebt:

C <form action="<?=htmlentities($action)?>" method="post"> <div class="field_container"> <label for="email">gebruikersnaam (e-mail):</label> <input type="text" name="email" id="email" value="" /> </div> <div class="field_container"> <label for="wachtwoord">wachtwoord:</label> <input type="password" name="wachtwoord" id="wachtwoord" value="" /> </div> <div class="field_container"> <label for="wl-login">&nbsp;</label> <input type="submit" name="wl-login" value="Stuur op!" />

Afbeelding 2.7 Structuur en bestanden voor het login-module

Page 27: 2 Een website bouwen - Welkom bij Pearson Benelux BV

52

PHP EN MYSQL de basis

</div> </form>

In dit formulier kan de action worden aangepast door de template-engine. n Het stijlblad in style.css is aangepast zodat er alleen percentages en em’s in ge-

bruikt worden:

C .page { width: 80%;}label { display: block; text-align: left; padding-right: 10px; font-size: 0.8em;}form { max-width: 200px; width: 80%; border: solid 1px; padding: 0.5em; font-size: 1em;}.field_container { padding-top: .5em;}input[type="text"] input[type="password"] { padding-top: .4em; width: 95%;}input[type="submit"] { padding-left: 0;}

Dit levert misschien niet het mooiste formulier van de wereld op, maar het schaalt wel netjes, waarmee het voldoet aan onze eis van “zichzelf aanpassend web ontwerp”, zoals het plaatje in afbeelding 2.8, genomen op een iPhone, naast een PC plaatje, laat zien.

n In het bestand login.sql hebben we de SQL bewaard die nodig is om de tabellen webuser en userauth te creëren.

n Er is in de map table van het raamwerk wl een bestand verschenen met de naam webuser.php. Dit bestand bevat de klasse WebUser. We laten hier als voorbeeld de methode checkwachtwoord() uit deze klasse zien:

C public function checkWachtwoord($email, $wachtwoord){ // het wachtwoord moet al met md5 geencrypt zijn $sql = "SELECT id, naam, email, wachtwoord, registratiedatum

Page 28: 2 Een website bouwen - Welkom bij Pearson Benelux BV

53

2 Een website bouwen

FROM webuser WHERE email = ? AND wachtwoord = ?"; $args = array("ss", $email, $wachtwoord); $this->mydb -> execute_bound_query($sql, $args, true); return ($this->mydb->num_rows() === 1); }

n Omdat er in de methode gebruik wordt gemaakt van parameter binding, is er geen gevaar voor SQL-injectie. Dit gebeurt via de methode execute_bound_query(), die we eerder hebben besproken in hoofdstuk 11, toen we onze databaseklasse voor het raamwerk fw presenteerden. De andere methoden van de klasse WebUser laten we als oefening aan u om te bestuderen.

n Ten slotte is er in de map view een templatebestand met de naam test.inc. Dit bevat de HTML-code voor een minipagina, zodat we onze loginmodule makkelijker kunnen testen.

C <html> <head> <meta content="width=device-width, initial-scale=1.0" name="viewport"> <title>Loginformulier</title> <link rel="stylesheet" type="text/css" href="../wl/site/login/css/style.css" /> </head> <body> <div class='page'> <?=$loginForm?> </div> </body></html>

n Van belang voor het testscript wat we nu gaan maken is de regel <?=$loginForm?>, want daar moeten we ons formulier gaan neerzetten.

Afbeelding 2.8 Loginformulier op pc en iPhone.

Page 29: 2 Een website bouwen - Welkom bij Pearson Benelux BV

54

PHP EN MYSQL de basis

2.4.5 Test de loginmodule

We hebben een testscript geschreven om ons logintemplate te testen. Het is een script van het type controller, daarom is het direct in de map debasis/bonushoofdstuk02 geplaatst, met de naam cntrl_loginTest.php.

We beginnen met het laten zien van de testpagina:

C <?phprequire 'config.inc';if (!isset($_POST['wl-login'])) {// maak de test pagina$loginTest = new \fw\tmpl\Template('../wl/site/login/view/test.inc');// maak het loginformulier met de action$action = $_SERVER['PHP_SELF'];$loginForm = new \fw\tmpl\Template('../wl/site/login/view/index.inc');$loginForm->set('action', $action);// plaats het login formulier in de testpagina$loginTest -> set('loginForm', $loginForm);echo $loginTest -> fetch();}

Merk op dat de action van het formulier naar het script zelf verwijst en dat de functie htmlentities() uitgevoerd wordt vanuit het template, zodat u dit niet kunt vergeten.

We laten het formulier alleen zien als het nog niet was opgestuurd. In een echte pagina moeten we wat meer doen, namelijk als de login fout ging willen we het formulier ook opnieuw zien. Dat gaan we straks met behulp van het bijhouden van een sessie oplossen. Nu laten we de rest van het script zien, dat wordt uitgevoerd als $_POST['wl-login'] gezet is en er dus iemand op de knop Stuur op! heeft geklikt.

C if (isset($_POST['wl-login'])) { $form = new \fw\form\ValideerFormulier(INPUT_POST); $email = $form -> filterEmail('email'); $wachtwoord = $form -> filterWachtwoord('wachtwoord');

$user = new wl\table\WebUser(); if ($user -> checkWachtwoord($email, $wachtwoord)) { echo "Uw wachtwoord was goed."; $userrow = $user -> getCheckedUser(); echo '<br/>Hallo ', htmlentities($userrow['naam']), ', uw e-mail adres is: ', $email; } else { echo "Uw gebruikersnaam en/of wachtwoord was niet goed.";

$fouten = $form -> getFoutmeldingen();

Page 30: 2 Een website bouwen - Welkom bij Pearson Benelux BV

55

2 Een website bouwen

if (count($fouten) > 0) { echo "<br/><br/>Foutmeldingen:"; foreach ($fouten as $key => $value) { echo '<br/>', $value; } } }}?>

Een opmerking over het gebruik van $_POST['wl-login'] , terwijl u misschien $_POST['submit'] verwacht had. We hebben deze index voor de $_POST-array gekozen in de hoop dat we hierdoor minder gauw problemen krijgen met andere formulieren die op dezelfde pagina zouden kunnen staan.

In de code ziet u nu een object van het type ValideerFormulier gemaakt worden. We zijn deze klasse in hoofdstuk 8 al eerder tegengekomen en omdat de geboden functio-naliteit voor alle formulieren gebruikt kan worden hebben we de klasse toegevoegd aan het raamwerk fw. We hebben ook een nieuwe methode toegevoegd die het wachtwoord filtert. Het enige wat die methode doet is de functie md5() op het wachtwoord toepassen.

Daarna wordt het gefilterde wachtwoord gecheckt met de methode checkWachtwoord() van de klasse WebUser. Deze methode hebben we hierboven al laten zien.

Als het wachtwoord goed is, dan wordt de rij met getCheckedUser() opgehaald die door checkWachtwoord() al beschikbaar was gemaakt, en de naam wordt getoond. Deze me-thode is niets anders dan een fetch() op een al beschikbare rij.

Mocht de check mislukt zijn dan wordt een foutmelding gegeven en eventuele meldingen van de filterklasse getoond.

2.4.6 Fluidgrid met login

We gaan nu onze kennis toepassen om de module login in te bouwen in de fluidgrid-voorbeeldpagina. Het idee is, dat een loginformulier wordt getoond in plaats van de tekst in de linker kolom, als een gebruiker nog niet is ingelogd, of als het inloggen niet goed is gegaan. In het laatste geval wordt er ook een foutboodschap getoond.

We maken een nieuwe toepassing met een nieuw controller-script. De toepassingscode is in eerste instantie een kopie van demap debasis/bonushoofdstuk02/fluidgrid-vb, met inhoud, die we de naam geven: debasis/bonushoofdstuk02/fluidgrid-login-vb. Het controller-script debasis/bonushoofdstuk02/cntrl_fluidgrid.php kopiëren we naar debasis/bonushoofdstuk02/cntrl_fluidgrid-login.php. Als u het nieuwe controller-script uitvoert, dan ziet u de oude voorbeeldpagina van het fluidgrid verschijnen.

Page 31: 2 Een website bouwen - Welkom bij Pearson Benelux BV

56

PHP EN MYSQL de basis

We gaan nu beginnen met de veranderingen te maken om het loginscherm te laten zien.

Afbeelding 2.9 laat het browserscherm zien als een gebruiker voor de eerste keer http://localhost/debasis/bonushoofdstuk02/cntrl_fluidgrid-login.php in de adresbalk typt.

Kijk nog even terug naar paragraaf 2.3.1 waar het basistemplate voor de fluidgrid-pagina wordt getoond en naar afbeelding 2.5, die de pagina schematisch laat zien. U ziet dat de tekst in de linkerkolom wordt gerepresenteerd door de variabele $article.

Er zijn drie mogelijkheden: n De gebruiker is al eerder ingelogd of er zijn geldige gebruikersgegevens opgestuurd. In

dit geval laten we de tekst die nu in bonushoofdstuk02/fluidgrid-login-vb/view/article.inc staat zien. We passen article.inc iets aan, zodat we de gebruiker die succesvol is ingelogd kunnen begroeten. Bovenin article.inc zetten we:

C <div class="hellouser"> <?=$helloUser?></div>

n De gebruiker is nog niet ingelogd en heeft nog geen gebruikersgegevens opgestuurd. Dit is typisch het geval als de pagina voor het eerst getoond wordt. We laten nu het loginformulier zien dat in wl/site/login/view/index.inc staat in plaats van de articletekst.

n De gebruiker heeft foute gebruikersgegevens opgestuurd. In dit geval willen we het log-informulier nogmaals laten zien met een foutmelding eronder. We passen wl/site/login/view/index.inc iets aan, zodat er een foutboodschap getoond kan worden. We zetten onderaan:

Afbeelding 2.9 Fluidgrid waar de gebruiker nog moet inloggen

Page 32: 2 Een website bouwen - Welkom bij Pearson Benelux BV

57

2 Een website bouwen

C <div class="loginerrors"> <?=$loginerrors?></div>

gEEf gEEN vEiLigHEiDSgEgE vENS wEg!

Soms ziet u dat u een melding krijgt dat het wachtwoord niet klopt als u daarmee een fout maakt. Daaruit kunt u concluderen dat de gebruikersnaam wel klopt. De hacker kan dat ook en hij kan met meer kans het wachtwoord achterhalen en uw site binnensluipen, dan wanneer u alleen zegt dat de combinatie van gebruikersnaam en wachtwoord ongeldig is.

We hebben nu het view-gedeelte aangepast om het nieuwe loginscherm te kunnen tonen. We moeten nu nog iets doen om te kunnen onthouden of een gebruiker is ingelogd en we moeten de controller aanpassen om op het juiste moment de juiste informatie te tonen.

2.4.7 Sessie-informatie voor fluidgrid met login

Als een ingelogde gebruiker de pagina verlaat, en weer terugkeert zonder eerst de brow-ser te hebben afgesloten, of als de toepassing meerdere pagina’s bevat, dan moet bekend blijven dat de gebruiker al is ingelogd. Zoals kort in hoofdstuk 11 besproken, kan dit door gebruik te maken van sessies. We beginnen ieder script dat bij de toepassing hoort met session_start(); en we houden gegevens die we tijdens de sessie willen bewaren bij in de super global array $_SESSION.

In de praktijk gebeurt het vaak dat naarmate de toepassing groeit, de sessievariabelen een onoverzichtelijke brei gaan vormen. We willen daarom een strakke naamgevingscon-ventie voorstellen. In ons voorbeeld willen we de id van de gebruiker bewaren tijdens een sessie, maar ook de naam, om die telkens te kunnen laten zien, zonder deze eerst uit de database te moeten halen. Als sessievariabelen zullen we $_SESSION['wl']['login']['id'] en $_SESSION['wl']['login']['naam'] gebruiken.

2.4.8 De fluidgrid-met-logincontroller

De verantwoordelijkheid van de controller is om het proces te besturen. De controller weet niet noodzakelijk hoe de login precies werkt of welke sessie-informatie er precies is opgeslagen. De controller weet wel dat er sessie-informatie is en dat er een loginfor-mulier moet zijn. Om het werk voor de controller makkelijker te maken, introduceren we een klasse LoginHandler die geplaatst moet worden in wl/site/login/model/login-handler.php. De klasse LoginHandler maakt gebruik van de klasse WebUser in wl/table, die in de database de gebruikersgegevens kan ophalen en verifiëren.

Page 33: 2 Een website bouwen - Welkom bij Pearson Benelux BV

58

PHP EN MYSQL de basis

De PHP-code in deze twee klassen zou u geen problemen mogen opleveren, want we heb-ben van veel stukken al voorbeelden gezien. Daarom laten we deze code hier niet zien. Wel tonen we het complete controllerscript cntrl_fluidgrid-login.php, zodat u van daar uit zelf de code in de twee klassen kunt vinden.

C <?phpsession_start();include ('config.inc');

$tpl = new \wl\site\fluidgrid\tmpl\FluidGridTemplate();

// vul alle templates in$head = new \fw\tmpl\Template('fluidgrid-login-vb/view/headsection.inc');$tpl -> set('headsection', $head);$menu = new \fw\tmpl\Template('fluidgrid-login-vb/view/menu.inc');$tpl -> set('pagehead', 'Weblampjes!');$tpl -> set('menu', $menu);$article = new \fw\tmpl\Template('fluidgrid-login-vb/view/article.inc');$entries = new \fw\tmpl\Template('fluidgrid-login-vb/view/entries.inc');$tpl -> set('entries', $entries);

$loginHdlr = new \wl\site\login\model\LoginHandler();

if ($loginHdlr -> formSubmitted()) { $loginHdlr -> validateForm(); // als OK, dan is de gebruiker ingelogt // als niet OK, dan is er een foutmelding bewaard}

if ($loginHdlr -> isLoggedIn()) { $naam = $loginHdlr -> getNaam(); $msg = '<br/>Hallo: ' . htmlentities($naam); $article -> set('hellouser', $msg); $tpl -> set('article', $article);} else { $loginForm = $loginHdlr -> makeLoginForm(); $tpl -> set('article', $loginForm);}

echo $tpl -> fetch();?>

Page 34: 2 Een website bouwen - Welkom bij Pearson Benelux BV

59

2 Een website bouwen

oEfENiNg 2 . 5 Maak een log-uit optie

Als u een andere gebruiker zou willen inloggen op onze fluidgrid voorbeeldsite, dan moet u eerst de browser sluiten om de sessie-informatie te verwijderen. U kunt daar iets aan doen door een log-uitoptie te maken.

n Maak een link onder de naam van de gebruiker. n Als de gebruiker op de link klikt, dan wordt de sessie-informatie verwijderd voor deze gebruiker.

Pas hiervoor de template article.inc aan, de controller en de klasse LoginHandler.