# Programmeren in PHP/Klassen
## Basis

    Programmeren, de basis/Klassen en objecten

### Voorbeeld
## Variabelen
### Encapsulatie

Soms kan het voorkomen dat je niet wilt dat anderen zien wat jij aan het doen bent (of het is niet belangrijk), kortom je wilt je gegevens (methoden en variabelen) afschermen tegen ‘misbruik van buitenaf’. In PHP4 had je hier geen of bijna geen mogelijkheden voor. Met de komst van PHP5 is hier verandering in gekomen; er zijn wat nieuwe keywords ingevoerd. Het encapselen van data houdt in dat jij aangeeft welke variabele/methoden de gebruikers van de klasse wel of niet mogen aanroepen.

#### Public

Het public keyword zorgt er voor dat iedereen de methode of variabele kan aanroepen, het maakt niet uit of dat van binnen of buiten de class is, dit was het standaard gedrag van PHP4. Als je geen ‘scope’ opgeeft, is dit ook het standaard gedrag van PHP5; ik raad je echter aan om wel altijd een scope op te geven, ook als die public is omdat de code dan zelf de documentatie is. Een voorbeeldje van het public keyword;
PHP-code:

#### Private

Als je wilt dat een variabele of methode alleen toegankelijk is binnen de class zelf gebruik je het private keyword. Het kan namelijk wel eens voorkomen dat je wilt bijhouden wat de status is van de class, zonder dat de gebruiker daar iets mee te maken heeft of zonder dat de gebruiker daar iets aan mag veranderen (een toegangsniveau op een bestandssysteem bijvoorbeeld, het zou fataal voor de beveiliging zijn als de gebruikers zomaar hun toegangsniveau aan konden passen). Het wordt aangeraden om al je class variabelen als private te declareren en er ‘toegangsfuncties’ voor te schrijven, deze functies zijn gekenmerkt door de prefix ‘get’ en ‘set’. Het maakt, bij het gebruik van dat soort functies namelijk niet uit of je een keer besluit om de naam van de variable te veranderen. Een voorbeeld volgt;
PHP-code:

#### Protected

Als een variable of method protected is, kan deze alleen gebruikt worden door classes die van de parent erven, of de class zelf.
PHP-code:

### Klasse constanten

Een constante is zoals de naam zegt, voor iedere klasse instantie hetzelfde. Het zijn dan ook geen variabelen want die kun je aanpassen en die waren te herkennen aan hun dollarteken. Voor de klasseconstanten heeft men een nieuwe operator toegevoegd om de waarde uit de klasse op te halen en een een nieuw keyword om een referentie naar zichzelf te krijgen (vanuit de klasse). Namelijk de '::' operator en het 'self' keyword. Het is een normale conventie om constanten met alleen maar hoofdletters te schrijven, maar anders mag natuurlijk ook. Je kunt maar een keer aan een constante een waarde toekennen, en dat is op het moment dat je deze definieert. Daarna blijft een constante zijn waarde behouden.
PHP-code:
Zoals je ziet wordt er geen instantie gemaakt van de klasse foo, maar wordt de klassenaam gebruikt, omdat het toch een constante is.
PHP-code:
Om dus in de klasse zelf aan een referentie naar BAR te komen gebruiken we niet $this-> maar self:: omdat $this een variabele zou impliceren, net als ->. Terwijl het hier gaat om constanten.

### Statische klasse variabelen

In PHP4 had je al statische variabelen, maar die golden alleen voor het bereik van de functie waarin ze gebruikt werden. In PHP5 kun je ook statische variabelen gebruiken die voor de klasse gedefinieerd zijn. Statische variabelen zijn eigenlijk een kruising tussen variabelen en klasse constanten, ze zijn voor iedere instantie gelijk maar je kunt er wel een nieuwe waarde aangeven (die waarde wordt dan overgenomen door alle andere instanties). Het wordt over het algemeen gezien als een slecht gebruik om statische variabelen te gebruiken. Een handige toepassing van statische variabelen is het singleton design pattern. (Wees hier echter voorzichtig mee!)
PHP-code:

## Speciale functies
### Constructor

Waar we in PHP4 de naam van de klasse gebruiken als constructor, is dat in PHP5 de speciale functie __construct geworden, deze verschilt verder niet van de constructor in PHP4 en wordt op de volgende manier gebruikt.
PHP-code:

### Destructor

PHP5 heeft ook ondersteuning voor destructors gekregen, deze worden (in tegenstelling tot constructors) aangeroepen als een object van de class wordt ‘vernield’, meestal is dit aan het eind van de pagina, maar het kan ook na een unset gebeuren. De naam van de destructor is __destruct.
PHP-code:

### __get

Het komt steeds vaker voor dat je eigenschappen wel public wilt maken, maar niet wilt dat ze aangepast worden. Of dat de variabele eigenlijk in een array thuis hoort, maar je die implementatie voor de gebruiker van de class verborgen wilt houden Daarvoor is __get in het leven geroepen. In OOP heet zoiets een property en functioneel zijn ze hetzelfde als die in C#. Echter is de implementatie in PHP anders.
PHP-code:
Het voordeel van __get; is dat het voor de gebruiker duidelijk is dat hij een variabele gebruikt, omdat dat ook zo is. In tegenstelling tot Java, waar nogal eens methoden voorkomen als getBar die totaal tegen de OOP principes ingaan. Zeker als je bar dan private maakt en het enige wat zo'n functie dan doet is `return bar;` tenzij je hetzelfde wilt gebruiken als hierboven. Anders is het een verkapte manier om variabelen publiek te maken.

### __set

Als je een functie hebt om op te vangen wanneer een variabele wordt opgevraagd, heb je er natuurlijk ook een voor wanneer een variabele van waarde wijzigt. Daar heb je __set voor. Set heeft twee parameters, een met de naam van de variabele en een met de waarde. Een voordeel van het gebruik van __set is dat je invoer kunt valideren voordat je daadwerkelijk de variabele van waarde laat veranderen.
PHP-code: PHP.index

### __call

__call Werkt hetzelfde als __get maar dan voor methoden aanroepen. Je kunt hiermee method overloading (meerdere methoden met dezelfde naam maar andere argumenten in dezelfde class) simuleren, maar het wordt wel een gigantische troep als je dat gaat doen.
PHP-code:
Let wel dat dit een extreem omslachtige manier is om te werken!

### __toString

Omdat klassen eigenlijk uitgebreide gegevensstructuren zijn, net als bijvoorbeeld een integer maar dan uitgebreid, is het natuurlijk handig om een manier te hebben om de interne waarde van je klasse weer te geven, bij bijvoorbeeld een echo. Net als dat
PHP-code:
Gewoon `12` naar de uitvoer schrijft. Waarom zou een klasse dat niet mogen? Of kunnen? Daarvoor heeft PHP de methode __toString voor bedacht. Deze neemt geen argumenten, en moet een string returnen. Stel je hebt een klasse die de getallen 1 tot en met 10 moet uitbeelden. Dan krijg je zoiets;
PHP-code:

## Interfaces

Een interface legt de functies die gebruikt worden in de class vast, om zo polymorfie toe te passen. Polymorfie wil letterlijk zeggen dat een object in meerdere vormen voor kan komen. In een interface kan je geen variabele definiëren, omdat dat helemaal niet van belang is voor de eindgebruiker van de class. Net als dat de interface van een website alleen belangrijk is voor de eindgebruiker (wat maakt het hem/haar nou uit wat er achter de schermen gebeurt, als het maar werkt). Je kunt ook geen instance van een interface definiëren en als een class niet alle functies uit die interface implementeert wordt deze class een abstracte class. Doordat iedere class die de interface implementeert, de functies heeft die in de interface beschreven zijn, mag je er blind op vertrouwen dat die functies ook bestaan, wat soms (bij gegevensvalidatie bijvoorbeeld) enorm handig kan zijn. Een voorbeeld van 'polymorfie' met behulp van een interface.
PHP-code:
Zoals je hier kan zien, bevat de array $_FOOS instantie van de classes foobar en barfoo, welke beide de interface bar implementeren (die de functie foo dicteert.) Je kunt er dus blind op vertrouwen dat ze allebei de functie foo bevatten.

## Meerdere interfaces implementeren

Het is mogelijk om een class meerdere interfaces te laten implementeren. Het verschil met abstracte classes (hieronder besproken) is dat je wel meerdere interfaces kan implementeren in een class, maar dat je een class maar 1 abstracte class kan laten 'extenden'. Om meerdere interfaces te implementeren doe je zoiets:
PHP-code:

## Abstracte classes

Hoewel interfaces je meer vrijheid geven in de implementatie daarvan, kan het wel eens voorkomen dat je ook wil dat er private functions worden gedeclareerd, die voldoen aan een eigen invulling, of dat je variabelen mee wil geven in je interface. Abstracte classes kunnen ook gewone methoden hebben, net als iedere andere klasse. Bij interfaces is dit allemaal niet zo. Een abstracte klasse bevat sowieso een abstracte method. Deze abstracte method geef je aan door ‘abstract’ voor de functie definitie te zetten. Je kan geen instantie maken van een abstracte klasse, of een klasse die niet alle abstracte methods van een klasse invult.
Kort samengevat is een abstract class dus een class waarvan een of meerdere functies niet zijn geïmplementeerd (ze hebben geen code), maar wel zijn gedeclareerd (de functie staat er wel). Een abstract class kun je daardoor niet los instantiëren, maar je kunt wel een andere class ervan 'afleiden' door de abstracte class te extenden.
PHP-code:

## Type hints

Het kan natuurlijk wel eens voorkomen dat je wilt dat je functie alleen een soort class of alleen classes met dezelfde interface in een functie wilt gebruiken, om bijvoorbeeld polymorfie toe te passen. Dit kan in PHP5 met type hints. Deze hints geven aan welk type class er gegeven moet worden als argument.
PHP-code:
Je kunt als hint zowel de naam van een class zelf als de naam van een interface opgeven.