OOP Beginnershandleiding (PHP5) Top PHP tutorial

Door Joren de Wit, 17 jaar geleden, 192.641x bekeken

Een inleiding tot het object geörienteerd programmeren in PHP5

Gesponsorde koppelingen

Inhoudsopgave

  1. Inleiding
  2. Object geörienteerd denken
  3. Foute denkwijze
  4. Object georiënteerd programmeren
  5. Visibility
  6. Naamgeving
  7. Constructor __construct()
  8. Voorbeeld: HTML tabel
  9. Inheritance
  10. Static methods en properties
  11. Abstract classes en Interfaces
  12. Slotwoord en referenties

 

Er zijn 49 reacties op 'Oop beginnershandleiding php5'

PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Richard van Velzen
Richard van Velzen
17 jaar geleden
 
1 +1 -0 -1
Hele goede tutorial voor beginners, heel duidelijk vooral. Niet dat ik het nodig heb, maar toch. :-)

2 kleine puntjes:
1) Je gebruikt *soms* Nederlandse en Engelse namen door elkaar heen. Dat leest niet erg prettig.
2)
Quote:
De enige method die afwijkt van de anderen is de escape() method. Deze is static gedefinieerd aangezien er voor de uitvoer ervan niet per se een connectie met een database nodig is en er dus geen instantie van enige class nodig is.

Dat is natuurlijk niet waar, escape functies gebruiken de database dus hebben ze wel een connectie nodig :-)
Robert Deiman
Robert Deiman
17 jaar geleden
 
Ik plaats mijn reactie die ik op phptuts heb gezet hier ook maar even.

- Een object max *normaal* 100 regels? -> Vind ik wel een gewaagde uitspraak. Werk je met user_input die je moet controleren, zijn eigenschappen van het "verzonden formulier". (zie het als een fysiek formulier) welke gecontroleerd moeten worden.
Je komt al snel over de 100 regels hoor.
- Weinig if/else statements, ligt er maar net aan of je dus controles gebruikt of niet. Daarbij kan het wenselijk zijn om loops te gebruiken, omdat je arrays als input kan gebruiken. Je roept dan een functie aan die de loop doet op de array, en de functie aanroept die steeds 1 zo'n item verwerkt. (wegens het eventueel wel van buitenaf ook rechtstreeks aan kunnen roepen van zo'n functie)
- Je geeft op het gegeven moment aan dat je voor nu even get/set methods gebruikt, maar dat je daar nog op terugkomt. Dat zie ik nergens terugkomen.

Verder een mooie en duidelijke tutorial. Voor mij wel 1 van de duidelijkste die ik heb gelezen. Jammer eigenlijk dat OOP "te groot is" om in 1 tutorial samen te vatten.
Toby hinloopen
toby hinloopen
17 jaar geleden
 
1 +1 -0 -1
"Document_PDF is fout: De DF moeten in kleine letters."

Is het in dit geval geen uitzondering omdat PDF een afkorting is?
En waarom doe je zowel Hoofdletters Per Woord EN lage streepje per woord?

DocumentPDF lijkt me toch wel de "beste" naam.

Zie ook hoe php.net zelf de naamgeving heeft van objecten en hun methodes:
http://nl.php.net/manual/en/book.dom.php
http://nl.php.net/manual/en/book.xmlreader.php
http://nl.php.net/manual/en/book.simplexml.php

Afkortingen horen gewoon met hoofdletters, samen met de 1e letter van ieder woord, zonder gebruik van lage streepjes.

Lage streepjes komen alleen voor in constanten (en bij PHP ook in de meeste functies... de logica...)

Ik raad mensen met OOP plannen aan eens de java tutorials te lezen. Ja, het is een andere taal, maar de OOP mogenlijkheden van java en PHP zijn vrijwel hetzelfde. (behalve dat je bij java meer kan dan bij PHP)

Zelf heb ik mijn OOP ook geleerd d.m.v. java, al is mijn OOP nog niet 100% "af".
Jelmer -
Jelmer -
17 jaar geleden
 
0 +1 -0 -1
De naamgeving die Blanche noemt zijn letterlijk de Zend naming conventions. Dat Zend zelf de naamgeving voor hun framework beschrijven geeft al aan dat er geen duidelijk beste manier voor PHP is. Het is puur wat jezelf prettig vindt, PHP dwingt niets af.

Voordeel van de streepjes in classnames is dat het heerlijk gemakkelijk door autoload kan worden omgezet in een pad naar een bestand. Dat is lastiger (maar niet onmogelijk) wanneer je een namen als DocumentPDFDecorator zou gebruiken.
Robert Deiman
Robert Deiman
17 jaar geleden
 
0 +1 -0 -1
@toby
Van niemand is de OOP 100% af, maar dat komt omdat iedereen het toch wel iets anders doet dan een ander het zou doen. Vaak is ook niet de 1e manier meteen beter, maar zijn het verschillende manieren om tot hetzelfde resultaat te komen.

Voor de 1 telt prestatie meer dan de leesbaarheid en andersom. 1 OOP standaard bestaat niet, en OOP is nooit 100% af. (zeker niet omdat vele programmeertalen zich ook steeds doorontwikkelen) Als je complete systemen op een goede en nette manier en met OOP kan ontwikkelen kan je gewoon OOP. Vaak kom je terwijl je bezig bent er nog achter dat er ook een andere (soms betere/ handigere) manier is om bepaalde dingen te programmeren. Als je dan al een heel eind op weg bent heb je soms niet de tijd/ zin/ mogelijkheid om helemaal terug te gaan werken om het te verbeteren/ veranderen.
Dat maakt je nog niet een mindere programmeur, er is niemand die (zonder zeer uitgebreide voorkennis) de boel in 1 keer helemaal goed en optimaal kan wegzetten.
Toby hinloopen
toby hinloopen
17 jaar geleden
 
0 +1 -0 -1
@Jelmer:
Owja, ik zie het. Vreemd dat de PHP developers zelf zich niet aan die regels houden.

Persoonlijk houd ik me aan de java regels, die ik ook lekkerder vind typen. Die lage streepjes zijn irritant :P

@robert:
je OOP is niet helemaal 100% af als je bepaalde problemen niet weet op te lossen (of er moeite mee hebt) in een OOP structuur. Zo ben ik (in java) een BBCode class aan het schrijven maar weet geen goede uitwerking voor de tags zelf en hoe tagtypes te verwerken. Ik ga er denk straks eens een topicje over maken op tweakers.
Joren de Wit
Joren de Wit
17 jaar geleden
 
0 +1 -0 -1
Richard:
Je gebruikt *soms* Nederlandse en Engelse namen door elkaar heen. Dat leest niet erg prettig.
In de inleiding maak ik daar een korte opmerking over. Ik heb in eerste instantie heb ik geprobeerd om alles naar het nederlands te vertalen, maar op een gegeven moment wordt het dan echt drama. Vertalingen van termen als inheritance, visibility, etc. bestaan uiteraard wel (overerving, zichtbaarheid) maar als je dat continue in een tekst gaat verwerken waarin je refereert naar de PHP code waar het wel in het Engels staat, zie je op een gegeven moment door de bomen het bos niet meer. Vandaar de bewuste keuze om bepaalde keywords in het Engels te houden.

Quote:
Dat is natuurlijk niet waar, escape functies gebruiken de database dus hebben ze wel een connectie nodig :-)
En daar heb je helemaal gelijk in! Aangepast. Het was al wat later gisterenavond dat ik dat hoofdstuk schreef.

Robert:
- Een object max *normaal* 100 regels? -> Vind ik wel een gewaagde uitspraak. Werk je met user_input die je moet controleren, zijn eigenschappen van het "verzonden formulier". (zie het als een fysiek formulier) welke gecontroleerd moeten worden.

Ik heb de tekst iets aangepast, maar ik blijf wel bij het standpunt dat je niet snel aan 100 regels code voor een class komt. Wat betreft die user input, ik zou elke validator als apart object zien. De daadwerkelijke validatie bestaat dan nog maar uit enkele regels waarin je door de opgegeven validators heen loopt en overal validate() aanroept.

Quote:
Weinig if/else statements, ligt er maar net aan of je dus controles gebruikt of niet. Daarbij kan het wenselijk zijn om loops te gebruiken, omdat je arrays als input kan gebruiken. Je roept dan een functie aan die de loop doet op de array, en de functie aanroept die steeds 1 zo'n item verwerkt. (wegens het eventueel wel van buitenaf ook rechtstreeks aan kunnen roepen van zo'n functie)

Ook hier geldt dat je over het algemeen veel minder if/else statements zult hebben dan in alternatieve procedurele code.

Quote:
Je geeft op het gegeven moment aan dat je voor nu even get/set methods gebruikt, maar dat je daar nog op terugkomt. Dat zie ik nergens terugkomen.

De getters zijn inderdaad nog niet de prullenbak in gegaan, maar de meeste setters worden op een gegeven moment vervangen door de constructor.

Tnx voor de reacties so far!
Joren de Wit
Joren de Wit
17 jaar geleden
 
0 +1 -0 -1
@toby: Robert en Jelmer geven het antwoord dat ik je ook wilde geven. In de handleiding geef ik ook expliciet aan dat er veel meer conventies zijn en nodig ik de lezer uit om daar zeker naar te kijken als die van Zend hem niet bevalt.

Quote:
Owja, ik zie het. Vreemd dat de PHP developers zelf zich niet aan die regels houden.
Dit is de conventie van het Zend Framework, maar het is niet gezegd dat het dé PHP naming convention is. Sterker nog, bij het framework wijken ze juist af van hetgeen de ontwikkelaars van PHP eerder bedacht hadden, dat geeft weer eens te meer aan dat er niet één goede manier is...
Jelmer -
Jelmer -
17 jaar geleden
 
0 +1 -0 -1
Ik vind het een hele goeie tutorial. Twee dingetjes die misschien nog toegevoegd zouden kunnen worden:

In het hoofdstuk over de constructor vervang je setUsername door de username gewoon mee te geven aan de constructor. Als uitleg geef je aan dat dit makkelijker is. Ik had ook een voorbeeld verwacht waarbij het eigenlijk noodzakelijk is, bijvoorbeeld een User_Store class die afhankelijk is van een instantie van PDO om te werken. Doordat je in je constructor afdwingt dat je de user_store altijd instantiëert met een instantie van PDO weet je zeker dat je user_store ook z'n pdo heeft. Wanneer je voor zo'n essentieel iets een setter zou gebruiken (wat ik veel beginners toch zie doen) heb je de rare situatie dat je de user_store hebt, maar dat hij niet werkt omdat je vergeten bent PDO er nog aan te koppelen.

In het hoofdstuk over inheritance of interfaces had je de Table class terug kunnen laten komen. Als je die een beetje aanpast zodat een Row en een Cell een eigen draw() method hebben (waar zeker iets voor te zeggen is, encapsulatie en verantwoordelijkheid) kan je het voorbeeld geven van bijvoorbeeld een StrongCell, die <strong>-tags om de content heen zet. Ik denk dat die situatie, waarbij je een class extend om hem specifiekere functionaliteit mee te geven, vaker voorkomt.
Nicoow Unknown
Nicoow Unknown
17 jaar geleden
 
0 +1 -0 -1
Waarom gebruik je per se __construct,
terwijl je ook gewoon (net zoals in bijna alle andere talen) de naam van de Class kan gebruiken.

Ook nog een kleine tip van mijn kant,, kijk maar of je het handig vind.
Maar ik maak voor iedere variable een getter en setter.
Deze setter roep ik ook aan om in de constructer variablen te zetten.
Zo kan je in je setter de foutafhandeling in bouwen.

Dan krijg je dus ongeveer dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php

/**
 * @author Nico Kaag
 * @copyright 2009
 */

error_reporting(E_ALL);

class User {    
    private $username;
    private $age;
    
    public function User($username, $age) {
        $this->setUsername($username);
        $this->setAge($age);
    }
    
    
    public function getUsername() {
        return $this->username;
    }
    
    public function setUsername($username) {
        $this->username = $username;
    }

    
    public function getAge() {
        return $this->age;
    }
    
    public function setAge($age) {
        if (is_numeric($age)) {
            $this->age = $age;
        }
else {
            throw new Exception('Age is not an Integer');
        }
    }
}


try {
    $user = new User('nicoow', '20');
    print_r($user);
    $user->setAge('12s');
}
catch (Exception $e) {
    echo 'Caught exception: '. $e->getMessage() ."\n";
}

?>

output:
User Object ( [username:private] => nicoow [age:private] => 20 ) Caught exception: Age is not an Integer

Dit scheelt maar 3 regels in je constructor, maar stel je voor dat je een controle hebt van 20 regels,, dan begint dat snel aardig aan te tellen.
Jelmer -
Jelmer -
17 jaar geleden
 
0 +1 -0 -1
@nico
Quote:
For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class.
bron

edit: ik denk eigenlijk dat dat deels gedaan is zodat parent::__construct() altijd de parent-constructor aanroept. Java kent daarvoor super() (toch?) en anders zou je in PHP, al dan niet per ongeluk, een constructor kunnen overslaan of per ongeluk aanroepen omdat ze de naam hebben van de class waarvan je overerft.

Wat betreft die setters, dat is inderdaad handig (sowieso is het goed om zoveel mogelijk code op te splitsen in functies en methods) maar niet alles hoeft te kunnen veranderen. (bijvoorbeeld een berekende eigenschap uit de database, postcount bijvoorbeeld) In zo'n geval zou je de setter private kunnen maken.
Joren de Wit
Joren de Wit
17 jaar geleden
 
0 +1 -0 -1
@Jelmer: bedankt voor de twee (hele goede suggesties) deze zal ik zeker meenemen zodra ik deze handleiding verder uitbreidt.

Nico:
Waarom gebruik je per se __construct,
terwijl je ook gewoon (net zoals in bijna alle andere talen) de naam van de Class kan gebruiken.
Dat is de methode die in PHP4 de enige mogelijkheid was en in PHP5 ook gebruikt kan worden. Naast de reden die Jelmer al noemt gebruik ik de magic method __construct() omdat ik dit ten eerste duidelijker vind maar deze method bovendien voldoet aan de naamgeving conventie die ik gebruik. De method User() doet dat niet...

Wat betreft die set methods, dat kun je overwegen. Mijn mening is dat het in de meeste gevallen onnodig veel regels extra code oplevert, vooral voor de properties waar geen controle voor nodig is. Als ik straks het onderwerp typehinting besproken heb, heb je minder methods voor controle nodig. Enige controles die je dan wilt gebruiken, kunnen dan ook in de constructor (of eventueel een enkele set-method mocht de controle erg lang zijn).
Boris Mattijssen
Boris Mattijssen
17 jaar geleden
 
0 +1 -0 -1
Interessante tut!
Nu ben ik benieuwd of dit een goede opzet van mijn klasse Page is:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<?php

/**
* CLASS
*/


class Page {
    private $_id;
    private $_title;
    private $_content;
    private $_parentId;
    private $_isHome;
    
    public function __construct($id, $title, $content, $parentId, $isHome) {
        $this->_setId($id);
        $this->_setTitle($title);
        $this->_setContent($content);
        $this->_setParentId($parentId);
        $this->_setIsHome($isHome);
    }

    
    private function _setId($id) {
        if(ctype_digit($id)) {
            $this->_id = $id;
        }
else {
            throw new Exception('Id is not a digit.');
        }
    }

    
    private function _setTitle($title) {
        if(ctype_alnum($title)) {
            $this->_title = $title;
        }
else {
            throw new Exception('Title is not alphanumaric.');
        }
    }

    
    private function _setContent($content) {
        $this->_content = $content;
    }

    
    private function _setParentId($parentId) {
        if(ctype_digit($parentId) || $parentId === null) {
            $this->_parentId = $parentId;
        }
else {
            throw new Exception('ParentId is neither a digit nor NULL.');
        }
    }

    
    private function _setIsHome($isHome) {
        if($isHome == 0 || $isHome == 1) {
            $this->_isHome = $isHome;
        }
else {
            throw new Exception('IsHome is not 0 or 1.');
        }
    }

    
    public function new() {
        mysql_query("
        INSERT INTO
            pages
            (
                title,
                content,
                parent_id,
                is_home
            )
        VALUES
            (
                '"
. $this->_title . "',
                '"
. mysql_real_escape_string($this->_content) . "',
                '"
. $this->_parentId . "',
                '"
. $this->_isHome . "',
            )
        "
);
    }

    
    public function edit() {
        mysql_query("
        UPDATE
            pages
        SET
            title        = '"
. $this->_title . "',
            content        = '"
. mysql_real_escape_string($this->_content) . "',
            parent_id    = '"
. $this->_parentId . "',
            is_home        = '"
. $this->_isHome . "'
        WHERE
            id         = '"
. $this->_id . "'
        "
);
    }
}


/**
* USAGE
*/


try {
    $page = new Page(null, 'Test pagina', 'Lorum ipsum...', 1, 0);
    $page->new();

    $page2 = new Page(1, 'Hoofd pagina', 'Lipsum lorum pipsum..', null, 1);
    $page2->edit();
}
catch (Exception $e) {
    echo 'Caught exception: '. $e->getMessage() ."\n";
}


?>

Met vriendelijke groet,
Boris
Niels K
Niels K
17 jaar geleden
 
0 +1 -0 -1
Respect voor dit stukje vakman schap
Joren de Wit
Joren de Wit
17 jaar geleden
 
0 +1 -0 -1
@Brie: je class ziet er goed uit tot het moment dat je de methods new() en edit() definieert. Die horen er namelijk niet in thuis. Een Page object weet alleen dingen over zichzelf en kan zijn eigenschappen aanpassen, maar kan zichzelf absoluut niet toevoegen aan een database!

De communicatie met een database moet via een ander object verlopen. Binnen dat object zul je dan de beschikken hebben over een of meerdere Page objecten die je vervolgens naar de database kunt sturen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
public function storePage(Page $page) {
  // Hier stuur je je gegevens naar de database
}
?>


ps. En uiteraard valt het aan te bevelen om de communicatie met de database zelf door een Database object af te laten handelen. In de class die de pagina moet opslaan, heb je dan naast het bewuste Page object ook nog een Database object nodig.
Boris Mattijssen
Boris Mattijssen
17 jaar geleden
 
0 +1 -0 -1
Blanche bedankt voor je reactie, ik ga er even mee puzzelen en maak er dan wel een topic van. Wel zo handig!

Groet
Joren de Wit
Joren de Wit
17 jaar geleden
 
0 +1 -0 -1
Brie, dat wilde ik net voorstellen. Laten we het hier enkel over de tutorial hebben :)

ps. Desalniettemin ben ik natuurlijk benieuwd naar de oplossing die je kiest...
Nicoow Unknown
Nicoow Unknown
17 jaar geleden
 
0 +1 -0 -1
Typehinting werkt ook maar half in php,
Je kan deze meegeven in de parameters van een functie,, maar dat is ook alles.

En hij geeft hele mooie foutmeldingen.
Zoals:
Catchable fatal error: Argument 1 passed to User::setAge() must be an instance of integer, integer given,

Oftewel, het is een "integer" maar het moet een "integer" zijn.
In mijn ogen "integer == integer" of niet dan?
Zelfs na een Typecast doet hij het nog niet.

Overigens is het met php ook niet mogelijk om een Typehint naar iets als numeric te geven.
Je zou dan,, als het ooit gaat werken,, alles moeten gaan typecasten, omdat een Post waarde ook altijd een string is.
De controlle met is numeric werkt prima, is_int niet.

Dus tot zover de goede controlle met Typehintinh *kuch*

Overigens nog even over de constructor.
Ik programmeer in meerdere talen (voornamelijk Java en C#), en dan is het wel lekker om 1 conventie aan proberen te houden, en aangezien __construct niet werkt in Java of C#, gebruik ik in PHP maar de class name, dan werkt het iig overal, behalve in de prehistorie.
Maar ik ben toch nooit erg goed in Geschiedenis geweest.
Toby hinloopen
toby hinloopen
17 jaar geleden
 
0 +1 -0 -1
@nico:
type casting werkt alleen voor object instances bij php inderdaad. Ik heb ook wel 'ff moeten lachen toen ik die genoemde error kreeg.

Misschien werkt het als je zelf een integer class maakt?

Maarja, houd het lekker bij java. Ik ben sinds kort ook begonnen aan java en vind het veel beter dan PHP.
GaMer B
GaMer B
17 jaar geleden
 
0 +1 -0 -1
@nico, geef je typhinting voorbeeld code eens, want ik vermoed dat je dit hebt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
<?php
public function iets(integer $int)[/code]
Joren de Wit
Joren de Wit
17 jaar geleden
 
0 +1 -0 -1
Nico, ik zal op dit onderwerp (de controles) zeker nog ingaan en daar de voor en nadelen van verschillende oplossingen tegen elkaar afzetten.

Wat betreft de constructor, het is uiteraard een persoonlijk keuze welke methode je fijner vindt werken en welke je gebruikt. Ik heb zelf beperkte ervaring in het programmeren in Java, maar ik weet hoe het daar werkt. Je zult dan ook met mij eens zijn dat de OO mogelijkheden veel groter zijn binnen Java dan binnen het (zeer) beperkte PHP. Met PHP5 is een goede stap gezet, maar het kan nog lang niet tippen aan de 'echte' OO talen.

Maar goed, we dwalen af. In PHP is het om eerder genoemde redenen waarschijnlijk verstandiger om __construct() te gebruiken. Nogmaals, het blijft een persoonlijk keuze en er is niet één goede manier aan te wijzen.
Nicoow Unknown
Nicoow Unknown
17 jaar geleden
 
0 +1 -0 -1
Java heeft ook wel zo z'n vreemde dingen hoor.
Zoals het verschil tussen string en String.
string is een "keyword" en String is een "Object"
Dit is ook zo voor integer en Integer.
integer kent geen toString() functie, en Integer wel.

De oplossing die jij nu geeft, kan ik me in vinden,, maar het klopt gewoon niet.
Dan kan je dus net zo goed weer een setter maken.
Edit:

@gamer
Inderdaag, heb ook Integer geprobeerd en Int en int
Maar dat mag niet baten.
Joren de Wit
Joren de Wit
17 jaar geleden
 
0 +1 -0 -1
Quote:
Dan kan je dus net zo goed weer een setter maken.
Nee, want dan kun je bijvoorbeeld vanuit een child niet meer naar de parent::__construct() verwijzen. Je zult dan altijd op de hoogte moeten zijn van de naamgeving van de methods in de parent class aangezien PHP geen andere manier kent om naar de (constructor van de) parent te verwijzen.
GaMer B
GaMer B
17 jaar geleden
 
0 +1 -0 -1
Quote:
@gamer
Inderdaag, heb ook Integer geprobeerd en Int en int
Maar dat mag niet baten.


Dan moet je maar eens de manual doorlezen:
Quote:
Traditional type hinting with int and string isn't supported.
Nicoow Unknown
Nicoow Unknown
17 jaar geleden
 
0 +1 -0 -1
Jah,, maar dat slaat toch nergens op,, maak dan geen type hinting.
Maar dat is toch een beetje het verhaal achter PHP,
Alles is er,, maar alles werkt eigenlijk net niet.
Joren de Wit
Joren de Wit
17 jaar geleden
 
0 +1 -0 -1
Quote:
Maar dat is toch een beetje het verhaal achter PHP,
Alles is er,, maar alles werkt eigenlijk net niet.
En dat kan ik niet ontkennen. Het is roeien met de riemen die je hebt, maar dan is er nog wel een verschil tussen 'efficient roeien' en 'roeien en niet vooruit komen' als je begrijpt wat ik bedoel ;-)
Jelmer -
Jelmer -
17 jaar geleden
 
0 +1 -0 -1
Typehinting voor scalar types is niet handig in PHP omdat het een dynamic typed taal is. '1' + '1' is net zo goed 2 als 1 + 1. Daarnaast gebruikt PHP de typehints niet om de goeie method te vinden, maar puur als controle. Er wordt door PHP wel geëxperimenteerd met stevigere controle maar naar mijn idee wordt het er niet veel duidelijker op.

Ik zou liever volledige operator overloading hebben, zodat we zelf een class Integer kunnen maken, en twee instanties daarvan of iets volledig willekeurigs bij elkaar op kunnen tellen met het plus-symbool. C++ style.
Joren de Wit
Joren de Wit
17 jaar geleden
 
0 +1 -0 -1
Jelmer:
In het hoofdstuk over inheritance of interfaces had je de Table class terug kunnen laten komen.
Ik heb inmiddels een nieuw voorbeeld aan de handleiding toegevoegd waarin het voorbeeld van de Table class uitgebreid wordt. Deze is te vinden in de handleiding op phptuts.nl.

Tnx voor de tip! ;-)
Mr.Ark
Mr.Ark
17 jaar geleden
 
0 +1 -0 -1
Ohhhh hartstikke bendankt Blanche !, ga hem binnenkort zeker doornemen. Nogmaals bedankt, tut ziet er goed uit. keep up the good work.
Nibulez
Nibulez
17 jaar geleden
 
0 +1 -0 -1
Maar wat is het nut nou precies van abstracte classes/functies en die interfaces.
Je geeft alleen maar aan wat er MOET gebeuren en dan kun je zonder die dingen ook wel doen, heb je ook minder code in je script staan.
Toby hinloopen
toby hinloopen
17 jaar geleden
 
0 +1 -0 -1
@Nibulez:
Een interface is een blauwdruk (definitie) van een class waarin je kan defineren wat een class moet kunnen (lees: welke functies het moet hebben) zonder dat het daarbij uitmaakt hoe de class dat uitwerkt.

Je kan bijv. de interface "database" maken en deze implementeren in de classes "mysql-database" en "filebased-database". Zo heb je 2 classes met exact dezelfde functies en werking, terwijl ze hun werk op 2 totaal verschillende manieren doen.

Het nut hiervan is dat beiden objecten voldoen aan het "database"-interface, waarna je via typehinting kan opgeven dat je een object wilt van een class die het database interface gebruikt. Voorbeeld:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?
class eenClassDieEenDatabaseGebruikt {
  public function gebruikDatabase(database $Database) {
  
  }
}

?>


Deze functie accepteert nu alle objecten die het database-interface gebruiken.

Het nut van typehinting op deze manier is een verkleinde kans op bugs omdat bepaalde bugs sneller gevonden worden. Immers, als je een object geeft die het interface niet heeft krijg je nu direct een error. Zonder typehinting krijg je dan pas een error wanneer er een functie gebruikt wordt die de classe van het object mogelijk niet heeft.

Verder, OOP is een garantie voor veel meer code dan niet-OOP. Dat komt simpelweg omdat je meer structuur en overzicht aan het scripten bent, waarbij je makkelijker en sneller bugjes kan opvangen.
Jelmer -
Jelmer -
17 jaar geleden
 
0 +1 -0 -1
Een interface zou je kunnen vergelijken met een opleiding. Een class die een interface implementeert kent het jargon.

Stel dat je een method "drawImageWithBorder" hebt die als eerste argument iets slikt dat in ieder geval de interface "Renderable" implementeert, en de interface Renderable zegt dat iedereen die die interface implementeert een method "render($resource)" moet hebben. Je "drawImageWithBorder" hoeft nu niet te weten wat voor argument je precies meegeeft, van wat voor class het is. Het weet zeker dat $argument->render($resource); werkt, want anders kan $argument die interface niet hebben geïmplementeerd. Puur controle dus. Of $argument nu een database, een projectie van een 3d-scene of een stuk tekst is, maakt niet uit en is niet interessant. Het voordeel daarbij van interfaces boven (abstracte) classes is dat je class niet verplicht ergens van af moet stammen. Iedere class-hiërarchie kan een interface implementeren.

Of die render() method daadwerkelijk doet wat hij moet doen, dat kan je niet controleren. Dat is gewoon een kwestie van goed programmeren en vertrouwen.
Joren de Wit
Joren de Wit
17 jaar geleden
 
0 +1 -0 -1
Interfaces leveren per definitie inderdaad meer code op, maar dat gebruik je zoals in voorgaande posts al gezegd is puur om af te dwingen dat classes een bepaalde structuur hebben.

Het verschil tussen interfaces en abstract classes zit hem in het feit dat je in abstract classes wel functionaliteit kunt programmeren. Met andere woorden, daar kun je wel volledig uitgewerkte methods in opnemen. Deze functionaliteit is echter niet volledig, daarom wil je (en kun je) van een abstract class geen instantie aanmaken. Je zou dan een half object krijgen en dat werkt niet. Alle childs van een abstract class erven de gedeeltelijke functionaliteit en maken deze vervolgens compleet door minimaal de methods die als abstract gedefinieerd zijn in de parent, van functionaliteit te voorzien. De childs hebben dus een stuk functionaliteit die overeenkomt (mits de bestaande methods niet overschreven worden) en een stukje eigen functionaliteit. In dit opzicht kost het je juist minder regels code aangezien je de gedeelde functionaliteit niet telkens opnieuw hoeft te programmeren.
Joren de Wit
Joren de Wit
17 jaar geleden
 
0 +1 -0 -1
Update: magic methods hoofdstuk toegevoegd.
Afra ca
Afra ca
17 jaar geleden
 
0 +1 -0 -1
Omdat deze uitstekende tutorial wel een kickje verdient (staat hij weer bij recente reacties :+ ), en ik dit wel interessant leesvoer vind voor velen aangezien het gerelateerd is aan OOP:

http://l0calh0st.tweakblogs.net/blog/4443/database-interactie-class.html

Ok, het is zeker nog niet perfect uitgevoerd, maar leerzaam is het zeker. Lees ook de comments uiteraard, waar uitstekende feedback wordt geleverd door onder andere YopY.
Robert van der Leest
Robert van der Leest
16 jaar geleden
 
0 +1 -0 -1
Geweldige tutorial :) Hier heb ik zeker wat aan
Wouter J
Wouter J
16 jaar geleden
 
0 +1 -0 -1
Alleen jammer dat het letterlijk van phptuts is gekopieerd:
http://phptuts.nl/view/45/

@blanche, sorry wist ik niet. Goede tutorials!
Joren de Wit
Joren de Wit
16 jaar geleden
 
1 +1 -0 -1
Blanche == Joren == Zelfde auteur ;-)
Niels K
Niels K
16 jaar geleden
 
0 +1 -0 -1
Komen er nog nieuwe hoofdstukken Blanche / Joren?
Joren de Wit
Joren de Wit
16 jaar geleden
 
0 +1 -0 -1
Dat staat echt al heel lang op de planning, heb het op dit moment alleen te druk met studie en werk. Maar in de toekomst zal er zeker nog weer e.e.a. aangepast/aangevuld/geupdatet worden...
Niels K
Niels K
16 jaar geleden
 
0 +1 -0 -1
Oh dat komt bekend voor :) Als je hulp nodig hebt geef je maar een gilletje hoor :)
Kris Peeters
Kris Peeters
15 jaar geleden
 
0 +1 -0 -1
Zeg, in plaats van setters en getters ...

Wat vinden jullie van een systeem zoals bv. jQuery het doet?

bv.
$("mijn_selector").html() // is een getter
$("mijn_selector").html('nieuwe html') // is een setter

Je laat de parameter blanco: dan gaat de functie er van uit dat je de inhoud wil halen; geef een parameter mee en de functie gaat er van uit dat je die parameter wil setten.

Dat kan je ook perfect toepassen in dit soort omgeving.
Joren de Wit
Joren de Wit
15 jaar geleden
 
0 +1 -0 -1
Is inderdaad een manier die je ook goed kunt toepassen. Daarbij ga je er natuurlijk wel vanuit dat je voor een getter nooit een parameter opgeeft, iets dat meestal zo is. Kun je je echter ook situaties indenken waarin je een getter een parameter meegeeft?
Wouter J
Wouter J
15 jaar geleden
 
0 +1 -0 -1
@Joren, bijv:

User::getByID(12)

Is een getter en die heeft een parameter nodig.

@Kris, jQuery doet nog veel meer leuks met de parameters. Maar het is inderdaad wel een leuke manier.
Eigenlijk is jQuery helemaal in OOP gemaakt...
Pim -
Pim -
15 jaar geleden
 
0 +1 -0 -1
Is dat nog wel een getter?
Ik zou een getter definiëren als een functie die een (protected) waarde van een object retourneerd. Je hebt dan daarbij geen extra gegevens nodig.
Andere 'get' functies vragen wel iets op, maar ik zou ze geen getters noemen.
@Kris,
In dat geval is het verschil in naamgeving slechts traditie.
Donny Wie weet
Donny Wie weet
13 jaar geleden
 
0 +1 -0 -1
Is deze OOP tutorial nog up to date? Ik moet voor mn studie beginnen aan OOP, en zoek een goede tutorial. Als iemand een betere heeft hoor ik dat graag.
Roel -
Roel -
13 jaar geleden
 
0 +1 -0 -1
Jahoor. In deze tutorial wordt de basis van OOP uitgelegd en dit zal dus niet (snel) verouderen.
Wouter J
Wouter J
13 jaar geleden
 
0 +1 -0 -1
Deze tutorial legt de basis van de OO syntax uit. Maar deze zal ook niet snel verouderen.

Tevens mag je er vanuit gaan dat tutorial gemarkeerd als top tutorial (te herkennen aan de 3 sterren) up to date zijn.
PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Aron van W
Aron van W
11 jaar geleden
 
0 +1 -0 -1
Wat je zegt over de naamconventies is een beetje paradoxaal:

’PHP heeft zelf een DateTime class’ (moet overigens DateTime-klasse zijn)
’Document_PDF’

1. PHP overschrijdt zijn eigen regels? Ik bedoel, Document >>> UNDERSCORE <<< PDF » DateTime (geen underscore). WTF?
2. PDF mag heus wel PDF zijn. PHP doet niet aan ENV (Entity Name Validation), behalve voor klassen met de zelfde naam.

Ook je regel dat er een underscore voor beschermde eigenschappen (property=eigenschap, might you want to change that) is puur mening.

Om te reageren heb je een account nodig en je moet ingelogd zijn.

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.