Oop in PHP 5
Zie je de class als een boom, dan vormen alle functies die in de class staan samen in het geheel die boom. (of de eigenschappen daarvan)
Een boom heeft bijvoorbeeld wortels-> Daar zou je een functie voor kunnen maken binnen die classe. Takken -> Ook een functie, bladeren ook, enz..
Als ik het idee goed begrijp zit het zo in elkaar:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
// je begint met een naam van de klasse. In dit geval een boom.
class cBoom{
private $sBladtype;
private $sBladkleur;
private $sBoomtype;
private $iBladaantal;
private $iBoomhoogte;
private $sResultaat;
//wanneer je de boom class aanroept moet er een instantie van een boom gemaakt worden waar we mee verder kunnen werken
function __construct($sBoomtype,$iBoomhoogte){
$this->sBladtype = 'standaard';
$this->sBladkleur = 'groen';
$this->sBoomtype = $sBoomtype;
$this->iBladaantal = 500;
$this->iBoomhoogte = $iBoomhoogte;
$this->sResultaat = 'De boom van het type '.$this->sBoomtype.' heeft een hoogte van '.$this->iBoomhoogte;
return $this->sResultaat;
}
function __destruct(){//maakt het resultaat weer leeg als de klasse is afgesloten
$this->sResultaat = "";
return $this->sResultaat;
}
function kleurblad($sBladkleur){
$this->sResultaat = 'Het is herfst, de bladkleur van de boom is nu '.$sBladkleur;
return $this->sResultaat;
}
function boomgroei($iBoomhoogte){
$this->sResultaat = 'De boom is gegroeid, hij is nu '.$iBoomhoogte.' groot.';
return $this->sResultaat;
}
function bladval($iBladaantal){
$this->sResultaat = 'Door de harde wind is de boom bladeren kwijt. Er zitten nu nog maar'.$iBladaantal.' bladeren aan de boom.';
return $this->sResultaat;
}
}
?>
// je begint met een naam van de klasse. In dit geval een boom.
class cBoom{
private $sBladtype;
private $sBladkleur;
private $sBoomtype;
private $iBladaantal;
private $iBoomhoogte;
private $sResultaat;
//wanneer je de boom class aanroept moet er een instantie van een boom gemaakt worden waar we mee verder kunnen werken
function __construct($sBoomtype,$iBoomhoogte){
$this->sBladtype = 'standaard';
$this->sBladkleur = 'groen';
$this->sBoomtype = $sBoomtype;
$this->iBladaantal = 500;
$this->iBoomhoogte = $iBoomhoogte;
$this->sResultaat = 'De boom van het type '.$this->sBoomtype.' heeft een hoogte van '.$this->iBoomhoogte;
return $this->sResultaat;
}
function __destruct(){//maakt het resultaat weer leeg als de klasse is afgesloten
$this->sResultaat = "";
return $this->sResultaat;
}
function kleurblad($sBladkleur){
$this->sResultaat = 'Het is herfst, de bladkleur van de boom is nu '.$sBladkleur;
return $this->sResultaat;
}
function boomgroei($iBoomhoogte){
$this->sResultaat = 'De boom is gegroeid, hij is nu '.$iBoomhoogte.' groot.';
return $this->sResultaat;
}
function bladval($iBladaantal){
$this->sResultaat = 'Door de harde wind is de boom bladeren kwijt. Er zitten nu nog maar'.$iBladaantal.' bladeren aan de boom.';
return $this->sResultaat;
}
}
?>
Via deze class kan ik nu een boom aanmaken en deze laten groeien en dergelijke. Zit ik zo goed met het principe, de opbouw en het idee erachter?
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Nogmaals aan zon soort klasse heb je vrij weinig, probeer iets om te zetten wat je al kan.
class User
eigenschappen:
- username
- niveau
functies
+ verifyLogin()
+ logOut()
+ etc..
en begin direct met PHP 5 dus overal even public/private/protected voor
Als je verder niks met die bladeren doet kan het gewoon als variabelen, wil je er ook dingen mee kunnen doen dan maak je er een losse klasse van.
Sinds PHP 5 behoor je gelukkig public/protected/private voor de functies zetten. Hiermee scherm je als het nodig is sommige functies af voor externe aanroep.
Je functies doen op dit moment niks, je moet de variabelen wel zetten met $this->var = newWaarde;
$private $sResultaat is hier een rare variabelen, je gebruikt hem alleen om wat in te zetten en dat direct terug te geven. Dit is niet nodig
Code (php)
1
2
3
4
5
2
3
4
5
<?php
function kleurblad($sBladkleur){
$this->sResultaat = 'Het is herfst, de bladkleur van de boom is nu '.$sBladkleur;
return $this->sResultaat;
}?>
function kleurblad($sBladkleur){
$this->sResultaat = 'Het is herfst, de bladkleur van de boom is nu '.$sBladkleur;
return $this->sResultaat;
}?>
mag ook:
Code (php)
__destruct is vooral voor het afhandelen van andere zaken (zoals het sluiten van een database verbinding, dingen wijzigen in een ander object etc.), niet voor het leegmaken van de eigen variabelen die zijn daarna toch weg.
Gewijzigd op 01/01/1970 01:00:00 door TJVB tvb
Zo gebruik je een member $sResultaat waarin je telkens de eigenschappen van de boom in zet. Dat is echter niet de bedoeling, want die eigenschappen worden nu juist bepaald door de verschillende members in je klasse.
Die members $sResultaat kun je dus uit je klasse halen en derhalve zal je constructor ook niets retourneren. Dat is ook eigenlijk het hele idee van de constructor: die maakt een instantie aan maar hoeft niets te retourneren.
Verder heb je dan de methodes als boomgroei() en bladval(). Ook hier hoor je niet te werken met $sResultaat, maar je hoort de verschillende members te updaten. Bijvoorbeeld:
De boom is nu met 10 gegroeid. Elke keer als je deze methode dus aanroept, groeit je boom. Ditzelfde kun je doen met bladval().
De kleurblad methode kun je inderdaad een parameter meegeven, maar wederom pas je dan de betreffende member aan en niet $sResultaat:
Tenslotte voeg je nog een extra methode toe die weergeeft hoe je boom eruit ziet:
Code (php)
@Rik: Ik vind een boom nog niet eens een gek voorbeeld om mee te beginnen hoor. Zo'n klasse heeft temniste betrekking op een realistisch tastbaar object. Dit in tegenstelling tot een user klasse, dat al een stuk abstracter is.
Rik bij OOP spreken we niet van functies maar van methodes.
Wat ik mis in deze klasse is dat ik een nieuwe kleur voor bladeren kan opgegeven echter deze wordt niet opgeslagen behalve dan in resultaat, idem voor de andere eigenschappen.
Verder zal je moet __toString een display van resultaat kunnen doen
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?php
class boom {
public $sType;
public $iHoogte;
public function __construct($sType,$iHoogte = 0) {
$this->sType = $sType;
$this->iHoogte = $iHoogte;
}
public function groei($iLengte) {
$this->iHoogte += $iLengte;
return true;
}
}
class tak {
public $iLengte;
public $memberOf;
public function groei($iLengte) {
$this->iLengte +- $iLengte;
}
public function assign(boom &$obj) {
$this->memberOf = $obj;
}
}
class blad {
public $sKleur;
public $memberOf;
public function setKleur($sKleur) {
$this->sKleur = $sKleur;
}
public function assign(tak &$obj) {
$this->memberOf = $obj;
}
}
$boom = new boom('beuk',5);
$tak = new tak();
$tak->assign($boom);
$bladeren = array();
for($i=0;$i<10;$i++) {
$blad = new blad();
$blad->setKleur('bruin');
$bladeren[] = $blad; //Een array met alle bladeren
$blad->assign($tak);
}
$tak->groei(3);
$bladeren[3]->setKleur('Geel');
$boom->groei(5);
?>
class boom {
public $sType;
public $iHoogte;
public function __construct($sType,$iHoogte = 0) {
$this->sType = $sType;
$this->iHoogte = $iHoogte;
}
public function groei($iLengte) {
$this->iHoogte += $iLengte;
return true;
}
}
class tak {
public $iLengte;
public $memberOf;
public function groei($iLengte) {
$this->iLengte +- $iLengte;
}
public function assign(boom &$obj) {
$this->memberOf = $obj;
}
}
class blad {
public $sKleur;
public $memberOf;
public function setKleur($sKleur) {
$this->sKleur = $sKleur;
}
public function assign(tak &$obj) {
$this->memberOf = $obj;
}
}
$boom = new boom('beuk',5);
$tak = new tak();
$tak->assign($boom);
$bladeren = array();
for($i=0;$i<10;$i++) {
$blad = new blad();
$blad->setKleur('bruin');
$bladeren[] = $blad; //Een array met alle bladeren
$blad->assign($tak);
}
$tak->groei(3);
$bladeren[3]->setKleur('Geel');
$boom->groei(5);
?>
Weet alleen niet precies hoe references werken (A) dus of de & goed staan en of het werkt weet ik niet.
Oké, bedankt alvast.. ik zie dat er een aantal reacties zijn waar ik wel wat mee kan. Ik zal het eens op mijn gemakje doornemen en de boel aanpassen. Ik was er al ooit mee begonnen, vandaar misschien dat ik wel op de goede weg zat. Ik wil er nu echt mee verder en in de nabije toekomst ook systemen op deze basis bouwen.
Heeft er iemand misschien een aanrader qua boek/website die wat verheldering brengt in OOP in PHP5? Het mag van mij zowel Engels of Nederlands geschreven zijn.
Auteurs: Ed Lecky-Thompson, Heow Eide-Goodman, Steven D. Nowicki, Alec Cove
Uitgever: Wrox
ISBN: 0-7645-7282-2
In het engels, uitgebreide behandeling van OOP.
Staat ook in phphulp boeken lib
Wordt wel al redelijke ervaring met PHP verwacht, maar niet persee PHP5
Quote:
Die & mag weg, objecten gaan automatisch by reference in PHP 5 :)public function assign(tak &$obj) {
Overigens is jouw opbouw ook precies zoals ik het zou doen, qua idee dan. Verschillende objecten voor manipuleerbare dingen zoals bomen en takken en bladeren,
Gewijzigd op 01/01/1970 01:00:00 door PHP erik
De klasse AppelBoom zou bijvoorbeeld nog een method dropApple kunnen hebben, een Spar, of een Boom in het algemeen heeft die niet.
Je zou daaruit ook de kleur van tevoren in de klasse Spar kunnen definiëren. Die is voor een Spar immers altijd groen, terwijl een Plantaan ook wel een ander kleurtje krijgt.
Dan zou ik een interface gebruiken en geen subklasse.
@phperik, tnx voor de tip :) Weet ik dat ook weer.
Ik legde precies hetzelfde als jij doet uit op MSN aan Robert, dat is wel apart.
@Kalle & WJ
Kalle heeft wel een punt naar mijn mening. Want een Boom op zich is niet nuttig: elk type boom heeft totaal andere eigenschappen. Een interface is dus best handig denk ik. Maar misschien is een abstracte klasse die je extend toch wel het beste. Dit is een beetje speculeren, omdat je niet weet of een Boom zelf nuttig is, omdat het eigenlijk een achterlijk voorbeeld is (PHP en bomen gaan niet echt samen). Het is dus maar hoe je het in de praktijk toepast. In mijn optiek heb je de class Boom nooit nodig en ben je altijd bezig met een type boom en dan is een interface juist behoorlijk geschikt (of abstracte klasse dus).
Ik denk dat ik met deze informatie toch eens met een user bezig ga, kijken of ik daar zo een beetje uit kan komen.
Bedankt voor de nuttige opmerkingen, daar heb ik wel wat aan en kan ik heus wel mee verder.
Bij deze een basis opzet:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php
// je begint met een naam van de klasse. In dit geval een user.
class cUser{
// daarna declareer je de te gebruiken variabelen
private $sUsername; // username van de gebruiker
private $sPassword; // password van de gebruiker
private $sEmail; // email van de gebruiker
private $sActivationcode; // activatiecode voor het account
private $iLevel; // level van de nieuwe gebruiker
function login(){
//logingedeelte
}
function logout(){
//uitlog gedeelte
}
function activate(){
// activeer het account
}
function sendmail(){
// stuur activatiemail/ gewone mail naar de user
}
function setlevel(){
// de beheerder kan bij users het level wijzigen
}
function subscribe(){
// nieuwe users aanmelden + controle op dubbele username enz.
}
}
?>
// je begint met een naam van de klasse. In dit geval een user.
class cUser{
// daarna declareer je de te gebruiken variabelen
private $sUsername; // username van de gebruiker
private $sPassword; // password van de gebruiker
private $sEmail; // email van de gebruiker
private $sActivationcode; // activatiecode voor het account
private $iLevel; // level van de nieuwe gebruiker
function login(){
//logingedeelte
}
function logout(){
//uitlog gedeelte
}
function activate(){
// activeer het account
}
function sendmail(){
// stuur activatiemail/ gewone mail naar de user
}
function setlevel(){
// de beheerder kan bij users het level wijzigen
}
function subscribe(){
// nieuwe users aanmelden + controle op dubbele username enz.
}
}
?>
Gewijzigd op 01/01/1970 01:00:00 door Robert Deiman
Er moet denk ik nog wel een "setLoggedin()" of een hele nieuwe class waarin sessies/ cookies gezet kunnen worden.
Verder zat ik nog wel te denken aan een "validate" class, waarin alles komt wat gevalideerd moet/ kan worden.
De variabelen worden nergens gezet.
En je functies hebben niet public/protected/private ervoor.
De getters en setters zijn niet nodig als je de variabelen nooit wijzigd. Maar ze zullen een keer ingesteld moeten worden dus als dat niet in de constructor gebeurt moet je wel de setters hebben.
Gewijzigd op 01/01/1970 01:00:00 door TJVB tvb
Dat de variabelen nergens worden geset, bedoel je tussen () in de functies?
-> Dat klopt, dat komt nog.. het ging nu om de basis opzet :)
Ik heb nu elke functie ook private gemaakt.. Een constructor hoeft dat niet voor he, omdat die sowiezo al echt in die class hoort?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
// je begint met een naam van de klasse. In dit geval een user.
class cUser{
// daarna declareer je de te gebruiken variabelen
private $sUsername; // username van de gebruiker
private $sPassword; // password van de gebruiker
private $sEmail; // email van de gebruiker
private $sActivationcode; // activatiecode voor het account
private $iLevel; // level van de nieuwe gebruiker
function __construct(){
//set uservariabelen
}
private function login(){
//logingedeelte
}
private function logout(){
//uitlog gedeelte
}
private function activate(){
// activeer het account
}
private function sendmail(){
// stuur activatiemail/ gewone mail naar de user
}
private function setlevel(){
// de beheerder kan bij users het level wijzigen
}
private function subscribe(){
// nieuwe users aanmelden + controle op dubbele username enz.
}
}
?>
// je begint met een naam van de klasse. In dit geval een user.
class cUser{
// daarna declareer je de te gebruiken variabelen
private $sUsername; // username van de gebruiker
private $sPassword; // password van de gebruiker
private $sEmail; // email van de gebruiker
private $sActivationcode; // activatiecode voor het account
private $iLevel; // level van de nieuwe gebruiker
function __construct(){
//set uservariabelen
}
private function login(){
//logingedeelte
}
private function logout(){
//uitlog gedeelte
}
private function activate(){
// activeer het account
}
private function sendmail(){
// stuur activatiemail/ gewone mail naar de user
}
private function setlevel(){
// de beheerder kan bij users het level wijzigen
}
private function subscribe(){
// nieuwe users aanmelden + controle op dubbele username enz.
}
}
?>
Edit: OMG, ik kon eerst niet eens submitten omdat ik JS met strict errors disabled had :S
Gewijzigd op 01/01/1970 01:00:00 door Willem Jan Z
Ik zou zo zeggen na wat te hebben gelezen over public/private/protected dat ik de meeste dingen protected kan zetten, en de sendmail function -> Een mail class lijkt me daarvoor wel een betere oplossing, die kan evt. wel vanuit de function sendmail() binnen de user class aangeroepen worden.
de functies login/logout/activate/setlevel/sendmail en subscribe worden allemaal binnen die class gebruikt en zijn dan nog wel via de constructor aanspreekbaar. -> Dus ik zou zeggen protected dan, klopt dat?