Beste PHPhulpers,

Ik ben al een aantal jaar bezig met PHP, en ben er ondertussen redelijk handig mee. Ik kom geregeld scripts tegen met classes en dus geschreven in OOP. Nu ben ik bekend met veel PHP-functies en manieren van het schrijven van scripts, en het lezen en begrijpen van classes lukt, maar ik was benieuwd of iemand mij het grote voordeel van het schrijven hiervan kan uitleggen.

Ik begrijp dat je denkwijze aangepast moet worden en dat je door iets OOP te scripten het vervolgens als je het goed hebt gedaan daarna probleemloos zou kunnen hergebruiken. Dat klinkt natuurlijk goed: je hoeft een bepaalde classe dan maar 1 keer te schrijven en daarna in je volgende project gemakkelijk overnemen.

Wanneer je je gaat verdiepen in OOP kom je tutorials tegen met omschrijvingen als "denk aan een auto, die bestaat ook uit verschillende elementen die samenwerken", of "het menselijk lichaam" waar je eten in moet stoppen om te blijven functioneren.

Mijn vraag is dan ook: voor welke toepassing is het ideaal om Object Oriented te programmeren? Wie heeft er een goed voorbeeld of een link naar een goede tutorial zodat het voor iedereen, met name beginnende PHP'ers, gelijk duidelijk is wat het nut is om deze denkwijze aan te wennen? Wanneer zou je dus een classe met methods gaan gebruiken in plaats van een simpele functie?

Ik hoop op positieve reacties, er wordt op deze website al genoeg tegen elkaar gezeurd over slechte scripts, voorbeelden en reacties, ik hoop dat dit in dit topic niet voor hoeft te komen. Mijn vraag is serieus en ik denk dat redelijk wat mensen iets aan goede voorbeelden kan hebben.

Alvast bedankt,
Johan.
OK, laat dus voor de TS duidelijk zijn dat dit een goed voorbeeld is hoe je OOP NIET zult toepassen ;-)

Voor de mensen die met OOP willen beginnen raad ik niet aan om meteen alles in classes te gieten maar begin bij simpele objecten.

Bijvoorbeeld: user, gastenboekbericht, nieuwsbericht, reactie, activiteit, ...
Als je deze dingen eenmaal goed kan, kan je gaaan uitbreiden.
Nee, inderdaad. Je leest wel eens berichten onder scripts die de poster dan OO noemt, maar wat dan een bij elkaar-raapsel van functies genoemd wordt. Dat was dan ook mijn doel niet.
Maar: als de toepassingen die ik noem niet per definitie goed zijn om te gaan maken door middel van OO, wat zou je er dan wel mee gaan maken?

Dit is dus een moeilijkheid bij het lezen van tutorials hierover, je krijgt voorbeelden van auto's, fietsen, mensen of vogels, maar wat ik wil maken (en al maak, maar dan zonder OOP) zijn dus dingen als een login-systeem, gastenboek, forum e.d. Wat zou mijn voordeel zijn om het vanuit het OOP-principe te gaan scripten en op welke onderdelen zou het van toepassing zijn?
Functies kan je heel goed gebruiken om programmeren (in de zin van implementeren) uit te stellen. Op die manier kan je abstracter over een oplossing nadenken, en hoef je je niet tegelijkertijd ook bezig te houden met hoe je dat moet vertalen in specifieke PHP code.

Bijvoorbeeld het plaatsen van een bericht in een gastenboek. Daarbij moet eerst gecontroleerd worden of er een bericht is opgestuurd, daarna of de inhoud geldig is, ook of het niet een spambericht is, en als dat allemaal goed is, moet het bericht worden toegevoegd aan het gastenboek. Vroeger, voor de functies, zou je nu al een hele lap code hebben. Maar dit probleem kan je in weze oplossen met slechts 4 functies. Het implementeren van die functies doe je daarna. Je deelt je grote probleem (hoe sla ik een bericht op wanneer iemand dat instuurt) op in kleinere stukjes.

Object geörienteerd programmeren is dat, en dan een stapje verder. In het voorbeeld met functies had ik het nog over een bericht, maar wat is dat bericht dan precies? Waarschijnlijk zou je standaard een tal variabelen los van elkaar hebben (eentje met een emailadres, eentje met de inhoud, etc) maar dan ben je weer bezig met details. Dus introduceren we de klasse Bericht. Een instantie van Bericht representeert, jawel, een bericht uit het gastenboek.

Voor mij is OO programmeren eerst programmeren op een hoger niveau, waarbij je nog niet alle details (de queries, de validatie-functies, etc.) hoeft uit te denken. Heb je dat klaar (dan kan je dat testen met dummy-data :) ) dan ga je naar een lager niveau, en ga je de details op dezelfde manier implementeren. En dan ga je de details daarvan weer implementeren, en zo ga je door totdat je weer met beide benen op de grond staat, en alleen nog maar standaard PHP functies aanroept.

Je kan dus prima OO programmeren zonder bibliotheken van anderen, maar de methode nodigt uit tot het gebruik van de bibliotheken van anderen. Zij hebben dan al zo'n detail helemaal voor je uitgewerkt, en die kan je dan gebruiken. Bevalt je die implementatie achteraf niet, dan werk je het detail opnieuw uit, maar de andere details hoef je dan niet meer aan te zitten, die zijn onafhankelijk (zolang je de interface van je details maar niet verandert, dwz de functie/method-namen, argumenten en waarden die ze teruggeven aan het hogere niveau)

Om jezelf in bescherming te nemen dat je niet details met elkaar gaat verweven heb je dingen als data hiding in OOP.

OOP komt met een keerzijde overigens. Omdat je op zo'n hoger niveau werkt, met data hiding en eigen verantwoordelijkheid van klassen moet je gaan nadenken over hoe je je klassen met elkaar gaat verbinden, hoe ze toegang kunnen krijgen tot dat wat ze nodig hebben (hoe kan de klasse/functie die de berichten opslaat bij de klasse (PDO bijv.) die verbinding heeft met de database?)

PHP heeft trouwens het (naar mijn mening) voordeel dat je procedureel programmeren en object geörienteerd programmeren heerlijk met elkaar kan mengen. Doe dat ook, vooral in het begin. In het voorbeeld van het gastenboek zou ik Bericht wel een klasse maken, maar het gastenboek zou ik in eerste instantie beheren met functies. (voeg_bericht_toe(Bericht $bericht), haal_berichten_op()) Daarna zal je geleidelijk door krijgen dat globale objecten, zoals de database verbinding die je dan globaal nodig hebt omdat die functies daarvan afhankelijk zijn, best gevaarlijk kunnen zijn (omdat je ze zomaar kan veranderen) en dat het misschien wel beter is om een aparte klasse te maken die Bericht-instanties in en uit de database haalt. En zo kan je geleidelijk meer dingen met objecten doen. Maar vooral in het begin zou ik niet in het MVC bootje springen, en verder gaan waar je nu met procedureel programmeren bent: mixen.
<?php

if(REQUEST_METHOD is POST)
{
$bericht = new Bericht();
$bericht->naam = $_POST['naam'];
$bericht->inhoud = $_POST['inhoud'];

if(!is_goed_bericht($bericht))
{
toon_melding('geen goed bericht');
toon_formulier($bericht);
}
if(is_spam_bericht($bericht))
{
toon_melding('spam');
toon_formulier($bericht);
}
else
{
voeg_bericht_toe($bericht);
toon_melding('bericht_toegevoegd');
}
}

toon_alle_berichten();
?>
Hoplakee, een gastenboek :)

edit: In een grotere app zitten overigens vooral classes voor standaard-problemen: inloggen, rechten, formulieren afhandelen, database toegang, templates, conversie van dingen, etc. Maar juist in het begin is het misschien goed om zelf te ontdekken wat handig is. Is veel leuker!

Mijn tip trouwens: wees heel pragmatisch. Programmeer alleen wat je op dat moment nodig hebt, implementeer niet dingen die je later denkt nodig te hebben. Die fout heb ik een hele tijd gemaakt: het probleem algemener oplossen dan dat in de situatie nodig was, en daarmee krijg je hele ingewikkelde code en een niet-ideale oplossing. Het klinkt heel leuk, omdat je zo'n algemenere oplossing kan hergebruiken maar in de praktijk doe je dat niet omdat hij net niet geschikt genoeg is, of omdat je nieuwe ervaring hebt en nu beter weet hoe je het probleem kan oplossen.
Hallo Jelmer,

Bedankt voor je verhelderende uitleg, ik denk dat veel mensen, zowel beginners als iets gevorderde PHP'ers (die zich ook in OOP willen gaan verdiepen) er zeker iets aan zullen hebben!

Mocht je (of iemand anders) nog meer tips/snippets hebben om mij en anderen in het OOP op weg kunnen helpen, dan houd ik me beleefd aanbevolen.

Grz. Johan.

// Edit: @ Hipska: bedankt voor de links, ik ga ze bestuderen :P

Reageren