Extra voorbeelden. 1 Objectenhierarchie. 2 Kalender



Vergelijkbare documenten
Verder zijn er de nodige websites waarbij voorbeelden van objectgeoriënteerd PHP (of Objec Oriented PHP, OO PHP) te vinden zijn.

Kleine cursus PHP5. Auteur: Raymond Moesker

Datatypes Een datatype is de sort van van een waarde van een variabele, veel gebruikte datatypes zijn: String, int, Bool, char en double.

Javascript oefenblad 1

Objectgeorïenteerd werken is gebaseerd op de objecten die door het systeem gemanipuleerd worden.

Uitwerking Tweede deeltentamen Imperatief programmeren - versie 1 Vrijdag 21 oktober 2016, uur

Uitwerking Aanvullend tentamen Imperatief programmeren Woensdag 24 december 2014, uur

IMP Uitwerking week 13

Je gaat leren programmeren en een spel bouwen met de programmeertaal Python. Websites zoals YouTube en Instagram zijn gebouwd met Python.

et Zend Framework bestaat volledig uit objectgeoriënteerde

Omschrijf bij ieder onderdeel van de methode de betekenis ervan. Java kent twee groepen van klassen die een GUI kunnen maken: awt en swing.

Versie 2: B C D D A C D A C C. Versie 3: C D A A B D A B D D. Versie 4: A D C C B D C B D D. Versie 5: B A D D C A D C A A

van PSD naar JavaScript

Het relaas van de beginnende programmeur. Het hoe en waarom van de assistent

Functies. Huub de Beer. Eindhoven, 4 juni 2011

A Inloggen. B - Wachtwoord Veranderen

DIAGNOSTISCHE TOETS Softwaresystemen UITWERKING

Vakgroep CW KAHO Sint-Lieven

De tag aan het begin van het PHPscript is "<?php" aan het einde van het PHPscript gebruik je "?>".

Inhoudsopgave Disclaimer... 3 Voorwoord... 4 Inleiding... 5 Het downloaden van XAMPP... 7 Het installeren van XAMPP... 8 Joomla installeren op

Uitwerkingen derde deeltentamen Gameprogrammeren Vrijdag 6 november 2015, uur

Gebruikershandleiding voor: Beperkte Password protectie met JavaScript

Foutcontrole met Javascript

MINICURSUS PHP. Op dit lesmateriaal is een Creative Commons licentie van toepassing Sebastiaan Franken en Rosalie de Klerk Bambara

Introductie en even voorstellen

Formulieren en waarden posten naar een view

Test Joomla op je PC 1

Les 7. Instap. CSS en views: schilderijen. Pas even de header aan van het thema en zorg ervoor dat er geen websitenaam en slogan te zien is.

Uitwerkingen Tweede deeltentamen Imperatief programmeren Vrijdag 15 oktober 2010, uur

5. Functies. In deze module leert u:

Formulier maken en opvangen met php


NAAM: Programmeren 1 Examen 31/08/2011

Programmeren 1 20 januari 2012 Prof. T. Schrijvers

Je hoeft je maar met twee bestanden bezig te houden:

A Inloggen. B - Wachtwoord Veranderen

Object Oriented Programming

Meehelpen met de ontwikkeling van nieuwe of verbetering van bestaande spellen. Pag. 1

Les 9: formulier controle met javascript.

Stroomschema s maken op papier

Disclaimer Het bestand dat voor u ligt, is nog in ontwikkeling. Op verzoek is deze versie digitaal gedeeld. Wij willen de lezer er dan ook op wijzen

PHP. Les 4 : Variabelen

Formulieren maken met Dreamweaver CS 4/CS 5

Versie 0.4. Documentatie Onsweb Club plugin voor KNKV verenigingen. Laatste wijziging: 19 juli 2012 Auteurs: Marien Dongstra, Sebastian Huisman

Access voor beginners - hoofdstuk 25

Hoofdstuk 1 Inleiding PHP 7 of ouder Hoe dit boek werkt 2

Uitwerking Tentamen Modelleren en Programmeren - versie 1 Woensdag 1 februari 2017, uur

PHP-OPDRACHT SITE BOUWEN

JavaScript. 0 - Wat is JavaScript? JavaScript toevoegen

2.4.4 LibreOffice Werkblad Mac

Handleiding website FMS-spaarnwoude.nl

Uitwerking Tentamen Modelleren en Programmeren - versie 1 Woensdag 1 februari 2017, uur

II. ZELFGEDEFINIEERDE FUNCTIES

HOGESCHOOL VAN AMSTERDAM Informatica Opleiding. CPP 1 van 10

Simon de schildpad J van Weert 1


Hosting. Bestelformulier en domeinnaamcontrole. Januari, WeFact B.V. Kuiper 7a 5521 DG Eersel Nederland. w: e:

Gebruiksvriendelijkheid: Gebruiksaanwijzing:

Modelleren en Programmeren

VAN HET PROGRAMMEREN. Inleiding

HANDLEIDING PROGRAMMEREN IN PASCAL (LAZARUS)

Stroomschema s maken op papier

Zelftest Programmeren in Java

Objective-C Basis. 23 april 2005, Eindhoven Patrick Machielse

Een spoedcursus python

Stroomschema s maken in Word

Werken met afbeeldingen in webpagina's

Programmeren (1) Examen NAAM:

Offerte s maken en aanmaken.

Aan het eind van deze lesbrief wordt uitgelegd wat het nut van OOP is en vind je een aantal oefenopdrachten.

NAAM: Programmeren 1 Examen 21/01/2011

Zonnepanelen Hoe krijg je de data op je website?

Uw TEKSTEDITOR - alle iconen op een rij

REKENVAARDIGHEID BRUGKLAS

Een ASP.NET applicatie opzetten. Beginsituatie:

Interactief blok 2 code opdracht 6 - wireframe

Programmeerstructuren met App Inventor

Variabelen en statements in ActionScript

WELKOM BIJ BOMBERBOT! LES 2: SEQUENTIES I LES 2: SEQUENTIES I WAAR GAAT DEZE LES OVER? INTRODUCTIE

In de tweede regel plaatsen we in het gereserveerde stukje geheugen een getal.

Uitwerking Eerste deeltentamen Mobiel programmeren - versie 1 Vrijdag 23 december 2016, uur

Inhoudsopgave... 1 Disclaimer... 3 Voorwoord... 3 Inleiding... 5 Het downloaden van XAMPP... 7 Het installeren van XAMPP... 8 Joomla installeren op

Gegevens uit een database tonen

1 Delers 1. 3 Grootste gemene deler en kleinste gemene veelvoud 12

Jarno Verhoogt 21 mei 2014 Stud. Nr Docent: Joost Faber. Deeltoets 2: Hoe maak je met javascript een eenvoudige slideshow?

Rapporten. Labels en Rapporten in Atlantis 1. Atlantis heeft twee manieren om output te genereren: 1. labels 2. rapporten (reports)

Een website maken met databasetoegang.

Tentamen Imperatief en Object-georiënteerd programmeren in Java voor CKI

HTML in Outlook Hoe zorgt u ervoor dat uw goed in beeld komt?

Een quiz plaatsen op je website

Visual Basic.NET. Visual Basic.NET. M. den Besten 0.3 VB. NET

Leaflet Web Maps with qgis2leaf

Handleiding Wordpress

Overerving & Polymorfisme

Tentamen Object Georiënteerd Programmeren TI oktober 2014, Afdeling SCT, Faculteit EWI, TU Delft

HvA Instituut voor Interactieve Media ActionScript 3.0

Beginselen van programmeren Practicum 1 (Doolhof) : Oplossing

Informatietechnologie 2. JavaScript. Functies, Objecten en toegang tot de DOM. Kristof Michiels

15. Google Tag Manager

Transcriptie:

Extra voorbeelden 1 Objectenhierarchie 2 Kalender

PHP EN MYSQL de basis 1.1 Uitgebreid voorbeeld van een objectenhierarchie We zullen een aantal kenmerken van objectgeoriënteerd programmeren toelichten met behulp van een voorbeeld. Het voorbeeld gaat over de taxonomie van het dierenrijk, u vast wel bekend, over zoogdieren en vissen en zo. U moet er niet te veel achter zoeken, want als u zou proberen te veel details aan ons voorbeeld toe te voegen, dan zult u merken dat de principes van de zuivere objectoriëntatie u in de steek zullen laten. Hierbij eerst een plaatje: Afbeelding 1.1 Een objectenhierarchie. 1.1.1 De klasse Dier Zoals u aan het plaatje kunt zien, is Dier de klasse waarvan alle andere klassen worden afgeleid, dus daar beginnen we mee: 2

Extra voorbeelden <?php abstract class Dier { protected $kleur = 'onbekend'; public function getkleur() { return $this->kleur; public function kanlopen() { return 'Ik weet het niet'; public function kanzwemmen() { return 'Ik weet het niet'; public function kanvliegen() { return 'Ik weet het niet';?> We stippen een aantal punten aan: De klasse Dier is gedefinieerd als abstract. Dit betekent dat u er niet echt een object van kunt aanmaken. We kunnen alleen objecten maken van klassen die een echte soort aanduiden, zoals Meeuw en Kabeljauw. Natuurlijk hebben dieren meer eigenschappen dan hier genoemd, in het kader van het voorbeeld vragen we ons alleen af of een dier kan vliegen, zwemmen, of lopen en of het dier misschien een kleur heeft. De property $kleur is als protected gedefinieerd, dus we moeten een public methode maken om de kleur te kunnen laten zien. Dit is de methode getkleur(). Stel dat we toch zouden proberen om een Dier object te maken: $moppie = new Dier(); We krijgen dan een foutmelding bij het uitvoeren van een script met deze coderegel erin: Fatal error: Cannot instantiate abstract class Dier in C:\xampp\htdocs\debasis\hoofdstuk05\extra-voorbeeld-dieren\test1.php on line 5 3

PHP EN MYSQL de basis 1.1.2 De abstracte klassen Vis, Zoogdier en Vogel We kunnen nog een paar abstracte klassen definiëren, voor Zoogdier, Vis en Vogel: abstract class Vis extends Dier { public function kanzwemmen() { return 'Ja'; abstract class Zoogdier extends Dier { public function kanlopen() { return 'Ja'; abstract class Vogel extends Dier { public function kanvliegen() { return 'Ja'; 1.1.3 Concrete klassen Deze code zegt dat vissen kunnen zwemmen, zoogdieren kunnen lopen en vogels kunnen vliegen, maar verder weten we nog niet veel over deze diersoorten en we kunnen nog steeds geen objecten maken. We breiden ons script daarom uit met een echt dier: class Meeuw extends Vogel { public function construct(){ $this -> kleur = 'wit'; Let erop dat we eigenlijk niets over meeuwen zeggen, behalve dat ze wit van kleur zijn. Laten we eens kijken naar het gedrag en de eigenschappen van Karel, een meeuw, met de volgende code (hoofdstuk05/extra voorbeeld dieren/test2.php): <?php require_once 'dieren.php'; echo '<br/>'; $karel = new Meeuw(); echo 'Kan Karel, een ', get_class($karel), ', vliegen? '; echo $karel -> kanvliegen(); echo '<br/>'; echo 'Kan Karel lopen? '; 4

Extra voorbeelden echo $karel -> kanlopen(); echo '<br/>'; $kleur = $karel -> getkleur(); echo "Karels' kleur: $kleur <br/>";?> Als u dit script uitvoert, dan krijg u te zien: Kan Karel, een Meeuw, vliegen? Ja Kan Karel lopen? Ik weet het niet Karels' kleur: wit Laten we bekijken waarom u dit resultaat krijgt. We beginnen met de definities van de dierenklassen toegankelijk te maken in ons testscript door require_once 'dieren.php'; aan het begin van ons script te zetten. De methode kanvliegen() staat niet in de klasse Meeuw, maar alle meeuwobjecten hebben ook alle Vogel eigenschappen en daar is kanvliegen() wel gedefinieerd en dat geeft het antwoord Ja. Voor het antwoord op de volgende vraag, kanlopen(), moeten we nog een stap hoger kijken, naar de methoden die in de klasse Dier staan vermeld, want voor vogels staat deze methode niet vermeld. Voor dieren in het algemeen weten we niet of ze kunnen lopen, dus het antwoord is nu Ik weet het niet. En dan de kleur. $kleur is een protected property in de klasse Dier. Dat betekent dat deze property beschikbaar is in subklassen van Dier, maar niet buiten Dier. We kunnen dus niet schrijven: $karel->kleur. Daarom hebben we een methode gemaakt getkleur(), die wel de property $kleur kan benaderen in Dier en die publiek toegankelijk is. Ten slotte de methode get_class(). Deze methode is onderdeel van een serie methodes waarmee informatie over objecten en klassen verkregen kan worden. De get_class() methode heeft als parameter een object en hij geeft de naam van de klasse waartoe het object behoort terug, of FALSE als het geen object is. We hebben in de klasse Vogel gezegd dat een vogel object kan vliegen. Dat is leuk voor meeuwen, roodborstjes en zelfs futen, maar hoe zit dat met pinguïns? Een pinguïn is wel een vogel, maar hij kan niet vliegen. We kunnen dit tot uitdrukking brengen door de klasse Pinguin als volgt te definiëren: 5

PHP EN MYSQL de basis class Pinguin extends Vogel { public function kanzwemmen() { return 'Ja'; public function kanvliegen() { return 'Nee'; Nu kunnen we dingen over Happy Feet te weten komen: <?php require_once 'dieren.php'; $happyfeet = new Pinguin(); echo 'Kan Happy Feet, de ', get_class($happyfeet), ' vliegen? ', $happyfeet -> kanvliegen (); echo '<br/>'; echo 'Kan Happy Feet lopen? ', $happyfeet -> kanlopen();?> De antwoorden zijn: Kan Happy Feet, de Pinguin vliegen? Nee Kan Happy Feet lopen? Ik weet het niet OEFENING 1.1 BREID HET DIERENRIJK UIT Breid het dierenrijk uit met een paar zoogdieren, zoals Beer, Walvis, Mens. En een paar vissen, zoals Zalm, Kabeljauw. Maak een methode: kanpraten(). Bedenk dat mensen en papegaaien kunnen praten, maak ook een klasse voor Papegaai. Maak een methode vindlekker(), die als parameter een voedingsmiddel accepteert. Maak een paar voorbeelden zoals: $pooh->vindlekker ('honing'); Maak een script om informatie over de klasse Meeuw te weten te komen, zoals: welke methoden zijn er, welke property s en de klasse waar Meeuw van is afgeleid (de superklasse). Hint: begin met zoeken naar get_class in het PHP manual, u komt dan uit bij een sectie over Classes/Objects en van daaruit kunt u de methodes vinden die u nodig heeft. 6

Extra voorbeelden 2.1 Project: Kalender We hebben nu voldoende kennis om een interessant project aan te pakken. Wat gaan we doen? We maken een kalender die u ook kunt inzetten als agenda. De eerste versie zal alleen de huidige maand laten zien, of een maand naar keuze. Eventueel zou u er iedere maand een andere foto naast kunnen zetten, net als bij een kalender aan de muur. Later, in een volgend hoofdstuk, zullen we manieren bedenken om afspraakinformatie aan uw kalender toe te voegen en met een beetje extra CSS of JavaScript, en natuurlijk beveiliging, is het ook mogelijk uw agenda te raadplegen op uw smartphone. Als datumprikker is een PHP kalender minder geschikt. U kent ze vast wel: als u een vliegticket via het internet bestelt, dan ziet u vaak een keuzemenu waarmee u op een makkelijke manier de reisdata kunt kiezen. Voor dit doel zijn uitstekende JavaScript componenten beschikbaar. Alleen als u een site moet bedienen waar JavaScript onmogelijk is, zou kunnen overwegen het met PHP te doen. 2.1.1 Kalenderontwerp De kalender biedt weinig interactie met de gebruiker. Alleen de knoppen voor volgende en vorige maand betekenen dat er een verandering van het getoonde moet optreden. De eerste versie van de kalender/agenda is statisch. We tonen de kalender in een HTML tabel, met ruimte voor aantekeningen. We hebben de afgekorte namen van de dagen van de week nodig, die op de eerste rij worden getoond. We tonen de dagen van de maand in de cellen van de tabel. We moeten weten op welke dag de eerste van de maand valt. We moeten weten hoeveel dagen de getoonde maand heeft. Technisch detail: voor de flexibiliteit van de vormgeving met CSS en de nette afsluiting van de tabel, moeten we het aantal dagen te weten dat nodig is om de onderste rij vol te maken. Techniek: we gaan objecten gebruiken! NB U vindt de oefenbestanden bij deze paragraaf in de map \hoofdstuk06\kalender. 7

PHP EN MYSQL de basis Afbeelding 2.1 Het voorlopige eindproduct. 2.1.2 De klasse KalenderMaand Om de functionaliteit die bij een kalendermaand horen, bij elkaar te houden, definiëren we een klasse: KalenderMaand. Om te beginnen geven we de klasse twee eigenschappen: jaar en maand, en de methoden om deze te zetten of te laten zien. We willen onze klasse later uitbreiden en scripts maken om een en ander te testen, daarom maken we een map, kalender, met een submap, versie1. In deze submap maken we twee bestanden: kalendermaand.php en kalendermaandtest.php. Let op! De naam van de klasse KalenderMaand is geschreven in CamelCase, met twee hoofdletters dus, de K en de M. Dit is volgens de naamgevingsconventie die we in het vorige hoofdstuk hebben uitgelegd. De naam van het bestand kalendermaand.php is in kleine letters, waarbij de naam hetzelfde is als de naam van de klasse. Dit maakt het mogelijk om later van de zogenaamde autoload-functie gebruik te kunnen maken, die het overbodig zou moeten maken om de klassebestanden handmatig in te voegen met include() of require(). Ook dit hebben we in het vorige hoofdstuk besproken. 8

Extra voorbeelden We maken een klasse die alle functionaliteit over een bepaalde maand bij elkaar houdt. Om te beginnen zal een object van de klasse KalenderMaand het jaar en het maandnummer moeten weten. Het allersimpelste begin is dan zó: <?php class KalenderMaand { public $jaar; public $maand; public function construct($jaar = null, $maand = null) { if (isset($jaar) &&!isset($maand)) { throw new Exception('Als jaar is gegeven, dan moet ook maand gegeven worden.'); else { if (isset($jaar)) { $this->jaar = $jaar; $this->maand = $maand; // Blijkbaar is er niets gezet, zet het huidige jaar en maand. else { $this->jaar = idate('y'); $this->maand = idate('m'); public function tostring() { return 'KalenderMaand, jaar: '. $this->jaar. ' maand: '. $this->maand;?> We zien dat er twee properties zijn: $maand en $jaar en dat we deze, als we een object creëren, als parameter kunnen meegeven. In de methode contructor()worden de argumenten (die toevallig dezelfde naam hebben, om u in verwarring te brengen), aan de properties toegekend. Er zijn echter een paar mogelijkheden waar we op moeten testen: het zou kunnen dat er geen argumenten worden meegegeven en in dat geval willen we de huidige maand tonen. Verder zou het kunnen dat iemand wel een jaar maar geen maand meegeeft, in dat geval hebben we een probleem en daarom gooien we een exception, die we straks in het script dat een object probeert te maken weer moeten opvangen. OEFENING 2.1 MEER CHECKS IN DE CONSTRUCTOR Eigenlijk zouden we in de constructor ook moeten testen of er wel een geldig jaar- en maandnummer wordt meegegeven. Voor het jaarnummer zou dat binnen de grenzen 9

PHP EN MYSQL de basis voor een unix-timestamp moeten vallen (lees de opmerking hierover in www.php.net/ manual/en/function.mktime.php) en voor het maandnummer, een nummer van 1 tot 12. Voeg deze code toe in de constructor-methode. Verder ziet u in de klassedefinitie van KalenderMaand een methode met de naam tostring(). Dit is een zogenaamde magische methode, wat u kunt zien aan de, net als construct() natuurlijk. Deze methode is handig om een stringrepresentatie van het object te kunnen laten zien. We zullen dit zo dadelijk in ons testscript gebruiken. De definitie van onze klasse KalenderMaand is nog verre van compleet, maar om niet door de bomen het bos niet meer te zien, laten we het hier even bij. 2.1.3 Een testscript voor de klasse KalenderMaand Om te kunnen zien of onze definitie tot zover klopt, maken we een testscript. Dit is een goede gewoonte in de programmeerwereld. We spreken meestal over een unittest, omdat we de test onderverdelen in kleine units en niet de hele toepassing tegelijk proberen te testen. <?php require_once 'kalendermaand.php'; echo "<pre>"; try { $kal = new KalenderMaand(); echo "Nieuwe KalenderMaand met nu: $kal\n"; $kal = new KalenderMaand(2012, 7); echo "Nieuwe KalenderMaand met 2010, 7: $kal\n"; $kal = new KalenderMaand(2009); echo "Nieuwe KalenderMaand met 2009: $kal\n"; catch (Exception $e) { echo 'Er is iets fout met het aanmaken van een KalenderMaand object: ', $e -> getmessage(), "\n"; echo "</pre>";?> De uitvoer van dit script is helemaal als verwacht: Tot zover loopt onze ontwikkeling prima, na een oefeningetje gaan we verder. Omdat we willen bewaren wat we tot nu toe gedaan hebben, maken we een nieuwe submap van de map kalender, en noemen hen versie2. Kopieer alle versie1 bestanden er naartoe. 10

Extra voorbeelden Nieuwe KalenderMaand met nu: KalenderMaand, jaar: 2011 maand: 12 Nieuwe KalenderMaand met 2010, 7: KalenderMaand, jaar: 2010 maand: 7 Nieuwe KalenderMaand met sept. 1944: KalenderMaand, jaar: 1944 maand: 9 Er is iets fout met het aanmaken van een KalenderMaand object: Als jaar is gegeven, dan moet ook maand gegeven worden. OEFENING 2.2 MEER TESTS IN HET TESTSCRIPT Probeer een ongeldige datum en kijk wat er gebeurt. Pas uw checks aan indien nodig. 2.1.4 De verkorte namen van de week De verkorte namen van de weekdagen staan als koppen boven de tabel. Om ze te maken kunnen we een array definiëren: $weekdag = array ('zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'); Als u zeker weet dat alleen Nederlands sprekende gebruikers naar uw kalender zullen kijken dan is dit goed genoeg. Maar natuurlijk willen we de mogelijkheid open houden om de locale te laten variëren en de kalender bruikbaar te maken voor andere talen. U zou het volgende kunnen doen: Met strftime() en de formaatstring %a kunt u de plaatselijke verkorte weekdagnaam vinden van de datum die u definieert. Begin op zondag, en dus een datum waarvan u zeker weet dat het een zondag is, 5 juni 2005 bijvoorbeeld. Maak een for lus die 7 keer telkens de volgende dag maakt, en de gevonden weekdagnaam in een volgend element van de array stopt. Plaats de code als methode in onze klasse KalenderMaand. protected function setweekdagen() { for ($i = 0; $i < 7; $i++) { $this -> weekdag[] = strftime("%a ", mktime(0, 0, 0, 6, $i + 5, 2005)); U ziet $this -> weekdag[]..., wat er op duidt dat we een nieuw property hebben gemaakt: protected $weekdag; We maken de methode protected, omdat we niet willen dat deze methode van buitenaf wordt aangeroepen. 11

PHP EN MYSQL de basis Omdat we de weekdagen maar één keer hoeven te vinden, voegen we een instructie toe aan het eind van de methode constructor(): $this- >setweekdagen(); OEFENING 2.4 PRINT DE VERKORTE WEEKDAGNAMEN Print de gevonden weekdagnamen netjes uit. Probleempje: u kunt van buitenaf niet bij de weekdagnamen. Maak als oplossing een publieke methode getweekdagen();. 2.1.5 Bereken de eerste dag van de maand In ons object van het type KalenderMaand hebben we en jaarnummer en een maandnummer als properties staan. We kunnen mktime() gebruiken om een Unix tijdstempel te maken van de eerste dag van de huidige maand: $eerste = mktime(0, 0, 0, $maandnr, 1, $jaar); En we gebruiken weer idate(), nu het w -formaat, om het dagnummer van die eerste dag te vinden: $edag = idate('w', $eerste);[eind code] Bijvoorbeeld: in juni 2005 valt de eerste dag op een woensdag en zal $edag de waarde 3 bevatten. OEFENING 2.5 MAAK EEN METHODE EERSTEDAGINMAAND() Om de code in de klasse KelenderMaand overzichtelijk te houden is het handig om een methode te definiëren die het dagnummer van de eerste dag in de maand teruggeeft. protected function eerstedaginmaand() { //... return $edag; Vul de functie in. OEFENING 2.6 MAAK EEN METHODE DAGENINMAAND() De methode om het aantal dagen in een maand te berekenen lijkt erg op de functie eerstedaginmaand(). Maak deze methode. Mocht u problemen hebben met een van deze twee oefeningen, spiek dan in de online code, in versie 2 van de klasse KalenderMaand. 12

Extra voorbeelden 2.1.6 De restdagen Hoeveel lege hokjes moeten we aan het begin en aan het eind van onze maandkalender maken om de rijen vol te maken? De berekening gaat zo: protected function restdagen($edag, $ldag) { $mm = ($edag + $ldag) % 7; if ($mm!= 0) $mm = 7 - $mm; return $mm; Wat hier staat is dat we het aantal lege hokjes aan het begin optellen bij het aantal dagen in de maand. (Het aantal lege hokjes aan het begin is evenveel als het gevonden dagnummer met de functie eerstedaginmaand(), zondag=0, maandag=1, et cetera) Dan berekenen we hoeveel we overhouden als we daar zo vaak als mogelijk 7 van aftrekken. Dit is de modulo operator %. Als de uitkomst 0 is dan zijn er geen resthokjes. Anders trekken we de uitkomst (in $mm) van 7 af en we hebben het gevraagde aantal. Ook dit stukje code plakken we als methode in onze KalenderMaandklasse. Voorbeeld: uit afbeelding 2.1 blijkt dat er 31 dagen zijn in december 2011 en dat 1 december op donderdag valt (dag 4). Dus: $mm = (4 + 31) % 7 = 35 % 7 = 0, want 5*7 is 35, dus er zijn geen restdagen aan het eind van deze maand. Aan afbeelding 2.1 te zien, klopt dit. OEFENING 2.7 VOEG DAGNUMMER TOE AAN DE KLASSE KALENDERMAAND Eigenlijk is het onhandig dat we het dagnummer niet weten als de maand waarvoor we een object van het type KalenderMaand maken, de huidige maand is. Doe er iets aan! 1 Maak een nieuw property voor dag. 2 Voeg een regel aan de constructor()-functie toe die het property zet (maar alleen als vandaag binnen de huidige maand valt). 3 Pas de functie tostring()aan. 2.1.7 We testen ons werk Laten we eens kijken of onze methoden goed werken. De methoden dagenin Maand(), eerstedaginmaand() en restdagen() zijn protected, we moeten dus een publieke methode maken om ons werk te laten zien: 13

PHP EN MYSQL de basis public function kalenderinfo() { $edag = $this -> eerstedaginmaand(); $ldag = $this -> dageninmaand(); $rest = $this-> restdagen($edag, $ldag); return "eerste dag: $edag, aantal dagen: $ldag, rest dagen: $rest "; Deze methode lijkt wel een beetje op de methode tostring()die we eerder gemaakt hebben, ik neem aan dat dit verder geen uitleg behoeft. En nu nog een testscript, dat we gewoon weer kalender-test1.php noemen: <?php require_once 'kalendermaand.php'; echo "<pre>"; try { $kal = new KalenderMaand(); catch (Exception $e) { echo 'Er is iets fout met het aanmaken van een KalenderMaandobject: ', $e -> getmessage(), "\n"; echo $kal, "<br/>"; echo $kal->kalenderinfo(), "<br/>";?> Voor 4 december 2011 krijgen we hieruit: KalenderMaand, jaar: 2011 maand: 12 dag: 4 eerste dag: 4, aantal dagen: 31, rest dagen: 0 Kijk maar op een kalender om te zien dat het klopt. Misschien verbaast het u dat zowel het dagnummer als de eerste dag een 4 is. Maar dat komt natuurlijk omdat 1 december in dat jaar op donderdag valt en donderdag de vijfde dag in de week is, waarbij zondag dag 0 is. 2.1.8 Een tabel met dagnummers We zijn nu klaar om de eigenlijke tabel te maken. We maken er meteen een methode in onze klasse Kalendermaand van. public function printmaand() { $edag = $this -> eerstedaginmaand(); $ldag = $this -> dageninmaand(); $rest = $this-> restdagen($edag, $ldag); 14

Extra voorbeelden echo "\n", '<table><tr>'; foreach ($this->weekdag as $dag) { echo "<td class='wday'>$dag</td>"; echo '</tr><tr>', "\n"; for ($i = 0; $i < ($edag + $ldag + $rest); $i++) { if ($i < $edag $i >= $edag + $ldag) echo '<td> </td>', "\n"; else { echo '<td>', $i - $edag + 1, '</td>', "\n"; if (($i + 1) % 7 == 0) echo '</tr><tr>', "\n"; echo '</tr></table>'; We beginnen met de berekening van de eerste dag, het aantal dagen en de restdagen. Daarna beginnen we met een HTML tabel, met als eerste rij de weekdagennamen in verkorte vorm, die we in onze property $weekdag hebben staan. In de tweede lus, een for lus, stappen we door het totaal van het eerste dagnummer, het aantal dagen en het aantal restdagen. Als het goed is, is dit een veelvoud van 7. 1 Print een leeg hokje als de lusteller kleiner is dan het eerste dagnummer (omdat zondag 0 is, gaat dit precies goed). 2 Print ook een leeg hokje (het of teken is ) als we het laatste dagnummer al hebben geprint en de lus teller dus groter of gelijk is aan de som van het eerste dagnummer en het aantal dagen. 3 Als we geen leeg hokje printen, dan printen we het dagnummer. De lusteller is bij het eerste cijferhokje al gelijk aan het dagnummer van de eerste van de maand, dus als we dat getal van de lusteller aftrekken dan staan we op 0. We moeten nu op 1 uitkomen, dus de formule is $i $edag + 1. 4 Voorbeeld: de lusteller staat al op 3 als we bij de woensdag zijn aangekomen waarop 1 juni 2005 valt. Dat was dagnummer 3, omdat we bij zondag op 0 beginnen. Dus de formule is 3 3 + 1. 5 Na zeven hokjes sluiten we de rij af en beginnen aan de volgende. 6 Ten slotte sluiten we de laatste rij en de tabel af. 2.1.9 We testen ons werk We maken een nieuw testscript, kalender-test2.php en we maken ook een.cssbestand om de tabel er een beetje beter uit te laten zien. 15

PHP EN MYSQL de basis We beginnen met het testscript: <!DOCTYPE html> <html> <head> <title>php Kalender</title> <link rel="stylesheet" type="text/css" href="kalender.css" /> </head> <body> <div class="kalender"> <?php require_once 'kalendermaand.php'; try { $kal = new KalenderMaand(); echo "<h2>", $kal->printtitle(), "</h2>\n"; $kal -> printmaand(); catch (Exception $e) { echo 'Er is iets fout met het aanmaken van een Kalender- Maand object: ', $e -> getmessage(), "\n";?> </div> </body> </html> We hebben er nu een net HTML document van gemaakt. Dat stelt ons in staat een CSS bestand in te voegen, kalender.css. De eigenlijke PHP code is maar heel kort, alles wat kennis vereist over kalenders hebben we verstopt (Engles: encapsulated) in de klasse Kalendermaand en de vormgeving zit opgesloten in kalender.css. Ik neem aan dat er weinig uitleg nodig is voor dit script. Merk op dat de PHP code ergens middenin het HTML document begint. De CSS valt buiten het bestek van dit boek. Een opmerking: Er staat nergens in de CSS hoe breed de tabel cellen zijn. Dat ze toch netjes uit elkaar komen te staan is te danken aan de class="wday" toevoeging in de eerste regel met de weekdagen. Probeer maar eens in het CSS bestand.wday te veranderen in.wdayx om te zien wat er gebeurt. Als het goed is, is uw resultaat zoiets als afbeelding 2.1. OEFENING 2.8 HIGHLIGHT VANDAAG Print de huidige maand met daarin het dagnummer van vandaag in rood, of vet gedrukt. 16

Extra voorbeelden OEFENING 2.9 PRINT 12 MAANDEN VANAF NU Maak een for-lus die in twaalf stappen de twaalf maanden vanaf de huidige maand afdrukt. Check of de jaarovergangen en maandovergangen goed verlopen. 2.2 De klasse TableView Alles werkt nu zoals het hoort, maar de oplettende lezer heeft vast enkele tekortkomingen in onze klasse KalenderMaand ontdekt. Het geen goed gebruik om inhoud met vormgeving te mengen, zoals we gedaan hebben in de methode printmaand(). Stel dat we een agenda zouden willen maken met een meer ingewikkelde HTML structuur en grote hokjes waar tekst in kan staan. Stel dat we de kalender op de Nederlandse manier zouden willen printen, namelijk de weekdagen links onder elkaar en eventueel weeknummers bovenin. De HTML in onze tabel is nogal knullig. De eerste rij met weekdagnamen zou beter in <th> tags gevat kunnen worden en om de tabel te kunnen gebruiken voor dynamische vormgeving hebben we ook <thead>- en <tbody>-tags nodig. Om dit op te lossen ontkoppelen we de HTML van de klasse KalenderMaand en maken we een nieuwe klasse die we TableView dopen. Voordat we verder gaan, maken we een nieuwe map, versie3 en we kopiëren de bestanden uit versie2 hier naartoe. We besluiten tot een ontwerp van de klasse TableView als volgt: De klasse TableView heeft één argument, een associatieve array met elementen thead en tbody. Eventueel kunnen we dit later uitbreiden met een id en een class en misschien meer. De tabel header is een array met kolomnamen. De meest logische invoer voor de tabel body lijkt ons een tweedimensionaal array te zijn. Dit resulteert in de volgende code: <?php class TableView { protected $thead; protected $tbody; public function construct($table) { $this->thead = $table['thead']; $this->tbody = $table['tbody']; // hier komt de methode printtable 17

PHP EN MYSQL de basis?> Zoals u ziet gebeurt er in de constructor niets anders dan het uit elkaar halen van de array die als argument is meegekomen. public function printtable() { echo "\n", '<table><thead><tr>'; foreach ($this->thead as $colhead) { echo "<th>$colhead</th>"; echo '</tr></thead>', "\n"; echo '<tbody>', "\n"; foreach ($this->tbody as $row) { echo '<tr>', "\n"; foreach ($row as $field) { echo "<td>$field</td>"; echo '</tr>', "\n"; echo '</tbody></table>'; De methode printtable() is erg eenvoudig. In twee foreach() lussen worden eerst de header en daarna de rijen geprint. Voor iedere rij is er een derde foreach() lus die elk veld van de benodigde <td> tags voorziet. Misschien vindt u deze klasse ook nog vrij simpel; zoals gezegd, we zouden het mogelijk kunnen maken een id of een class toe te voegen. En we zouden wat kunnen doen aan het opvangen van fouten. Maar we hebben hiermee een zeer belangrijke loskoppeling gemaakt van de klasse KalenderMaand (hoewel we daar nog wel iets aan moeten doen). OEFENING 2.10 GEBRUIK DE TABLEVIEW Maak een array met een paar rijen en een header. Print hem uit met de TableView. 2.2.1 Wijzigingen aan de KalenderMaand klasse Nu we onze TableView hebben, moeten we de HTML die in de klasse Kalender Maand wordt gemaakt er weer uit slopen. We moeten een tabelstructuur bedenken die we aan kunnen bieden aan de TableView. We gaan dit in twee stappen doen: Maak een methode asarray(), die een array retourneert waarbij in de lege hokjes een lege string staat en in de andere hokjes het dagnummer. Maak een methode kalenderusstyle() die de dagen in rijen organiseert, zodat er een kalender uitkomt zoals gebruikelijk in Angelsaksische landen en zoals afgebeeld in afbeelding 2.1 18

Extra voorbeelden OEFENING 2.11 MAAK DE METHODEN ASARRAY() EN KALENDERUSSTYLE() Met alle uitleg die we al eerder hebben gegeven zou u deze methoden moeten kunnen maken. Maar spieken is toegestaan. Opmerking: ook een kleine aanpassing aan de CSS is gemaakt, zie het CSS bestand in de versie3 map. Natuurlijk hebben we nog een testscript nodig, we zullen niet het hele script laten zien, maar de belangrijkste regels: <?php require_once 'kalendermaand.php'; require_once 'tableview.php'; try { $kal = new KalenderMaand(); catch (Exception $e) { echo 'Er is iets fout met het aanmaken van een KalenderMaandobject: ', $e -> getmessage(), "\n"; exit ; echo "<h2>", $kal -> printtitle(), "</h2>\n"; $maandtab = $kal -> kalenderusstyle(); $table = new TableView($maandtab); $table -> printtable();?> De code zal u inmiddels bekend voorkomen. Overtuig u er nogmaals van dat de kalender er zo uit ziet als in afbeelding 2.1. OEFENING 2.12 MAAK DE METHODE KALENDERNLSTYLE() Deze oefening is niet zo makkelijk, omdat u de arrays moet samenstellen uit niet opeenvolgende elementen. En het zou leuk zijn als de weekdagennamen links worden getoond met enige highlighting. 19