Hi,


Wie kan mij uitleggen wat nu het verschil is tussen public, private en protected in een PHP class?
Hoe en wanneer gebruik je welke als je een class gaat programmeren.

gr. Sebastiaan
Public wil zeggen dat je een eigenschap van buiten een class kunt aanspreken en wijzigen.

<?php

class Person {

public $name;

}

$person = new Person();
$person->name = 'Sebastiaan';

?>
Meestal (eigenlijk altijd) wil je dit niet, omdat iedereen nu zomaar alle eigenschappen kan aanpassen. Meestal wil je een bepaalde vorm van controle behouden. Daarom worden vaak 'setters' en 'getters' gebruikt. De eigenschappen, meestal 'properties' genoemd, maak je dan private (of protected als je de class zou extenden, maar daar zal ik je nu niet mee lastigvallen).

<?php

class Person {

private $name;

public function getName() {
return $this->name;
}

public function setName($name) {
if (empty($this->name)) {
$this->name = $name;
} else {
echo 'Error, name is already set!';
}
}

}

$person = new Person();
$person->setName('Sebastiaan');

echo $person->getName();

// Sebastiaan

$person->setName('Karel');

// Error, name is already set!

?>
Als ik je mag adviseren, dan raad ik je aan om altijd private te gebruiken (tenzij je classes gaat extenden dan heb je mogelijk protected nodig).

Ozzie PHP op 02/11/2020 14:43:21
Als ik je mag adviseren, dan raad ik je aan om altijd private te gebruiken (tenzij je classes gaat extenden dan heb je mogelijk protected nodig).

Zou het om die reden daarom eigenlijk niet beter zijn om altijd protected (als default) te gebruiken in plaats van private? Dit omdat private in zekere zin de principes van OOP tegengaat (uitbreidbaarheid).

Ik zou het dus omdraaien: tenzij je expliciete redenen hebt om iets niet te extenden gewoon protected gebruiken, al was het maar om dingen niet op voorhand uit te sluiten.
Thomas van den Heuvel op 02/11/2020 23:00:25

[quote="Ozzie PHP op 02/11/2020 14:43:21"]Als ik je mag adviseren, dan raad ik je aan om altijd private te gebruiken (tenzij je classes gaat extenden dan heb je mogelijk protected nodig).

Zou het om die reden daarom eigenlijk niet beter zijn om altijd protected (als default) te gebruiken in plaats van private? Dit omdat private in zekere zin de principes van OOP tegengaat (uitbreidbaarheid).
[/quote]
Daar valt iets voor te zeggen. Ik vind het zelf prettig om alles in eerste instantie op private te zetten en pas 'vrij te geven' op het moment dat dat ook echt nodig is, zodat je bewust kunt selecteren wat je wel en niet vrijgeeft. Maar jouw aanpak zou ook kunnen. Het belangrijkste is in ieder geval dat je niet alles (of beter gezegd helemaal niks) op public zet. En of je alles op private of protected zet daar valt voor beide keuzes iets voor te zeggen. Zolang je het maar consequent doet.
Ozzie PHP op 03/11/2020 01:12:09
En of je alles op private of protected zet daar valt voor beide keuzes iets voor te zeggen.

Nou nee, private druist gewoon in tegen het hergebruiken van code. Dit is niet een kwestie van smaak. Deze code zul je eerst aan moeten passen (private -> protected) om hier alsnog verder mee te kunnen. Waarom zou je dit op voorhand dichtmetselen?

Een extra muur bijzetten kan altijd. Een muur ergens alsnog uitslopen is gewoon extra werk.

Ozzie PHP op 03/11/2020 01:12:09
Zolang je het maar consequent doet.

Nou nee, niet als dit inhoudt dat je iets consequent verkeerd doet. Je moet een reden hebben om specifiek protected of private (of zelfs public) te gebruiken. Dit is niet enkel syntactische suiker. Het argument voor protected (versus private) is dat je direct kunt extenden. De reden voor private zou kunnen zijn dat je dingen expliciet niet wilt extenden, maar hoe vaak komt dat voor? Heb je daar praktijkvoorbeelden van? En blijkt uit het gebruik van de class niet al vanzelf dat het extenden niet zoveel zin heeft of niet logisch is? Dit hoef je niet expliciet/op voorhand af te dwingen met private, tenzij dit dus echt de bedoeling is maar nogmaals, hoe vaak is dat echt nodig?

Het is beter om dingen open te houden in plaats van dingen achteraf open te breken, het laatste is gewoon meer werk. Dit valt deels onder het kopje "defensief programmeren" waarbij je potentieel overbodig toekomstig werk uit de weg gaat.

Het is ook niet een kwestie van "vrijgeven" want het gebruik is nog steeds beperkt tot binnen de class, of met protected afgeleide classes van zo'n class.
Nogmaals wat jij zegt snijdt ook hout.

Ik programmeer graag defensief alsin dat ik properties graag beperk tot de eigen class tenzij anders nodig blijkt te zijn. Daarbij moet ik zeggen dat ik al een tijdje niet meer met OOP bezig ben geweest. Ik zal er eens over nadenken of het een goede gewoonte is om voortaan protected te gebruiken.

Wel is dan de vraag wat dan nog het bestaansrecht van private is?
Hm, hier staan een aantal interessante punten. Misschien is het interessant om private vs protected toch wat verder te verkennen.

Wat voor keuze je ook maakt (public, protected, private). Deze zou ergens op gebaseerd moeten zijn en een reden moeten hebben.

Dan is er misschien nog een andere overweging: elke keer als je deze afweging maakt, moet je hier tijd aan spenderen. Als je private meeneemt in deze overweging is het antwoord niet altijd even eenduidig. Misschien is het op enig moment onbekend of het handig is om iets later nog te kunnen extenden.

Je zou ook kunnen opteren voor een "simpele beslisboom": indien iets direct opvraagbaar zou moeten zijn via het object: maak het public. In alle andere gevallen maak je het (voorlopig) protected.

En ook: het gebruik van private kan zorgen voor "onvoorspelbaar" gedrag in je code. Indien je een methode extend in de veronderstelling dat deze protected was en kan het even duren voordat je in de gaten hebt dat stiekem toch de parent methode werd gebruikt omdat deze private was. In zekere zin zorgt private ook voor meer complexiteit.
>> Je zou ook kunnen opteren voor een "simpele beslisboom": indien iets direct opvraagbaar zou moeten zijn via het object: maak het public. In alle andere gevallen maak je het (voorlopig) protected.

Tja, keuzes ... persoonlijk denk ik dat het nooit verstandig is om een eigenschap public te maken, omdat je er dan geen enkele controle op hebt. Private, protected .. pfff ... mijn insteek komt inderdaad meer overeen met sommige van de reacties in jouw eerste link. Zet alles op private en wijzig het pas als het nodig is. Valt daar iets voor te zeggen? Ja, ik denk het wel. Valt er iets voor jouw insteek te zeggen ... zet het op protected voor het geval je het nodig hebt? Ja daar valt ook iets voor te zeggen. Ik denk dat het uiteindelijk dan toch een persoonlijke voorkeur is. Waar voel je je prettig bij? Plak je alvast een pleister om je vinger omdat je je misschien gaat stoten? Of plak je de pleister als je je gestoten hebt?
Ozzie PHP op 04/11/2020 01:06:12
persoonlijk denk ik dat het nooit verstandig is om een eigenschap public te maken, omdat je er dan geen enkele controle op hebt.

Dit "probleem" los je op door magic getters en setters te gebruiken ala https://www.yiiframework.com/doc/guide/2.0/en/concept-properties . Iets wat je ooit als een (normale) public var bent begonnen kun je daarna altijd nog via een getter en/of setter "wegstoppen" (incl. controle slag). Zonder dat je je hele codebase door hoeft (of iemand die jouw code gebruikt!) om overal van ->prop ==> ->getProp() te maken (of ->prop = $value ==> ->setProp($value) ).

Ja, ik weet het: overhead. Maar elke keer als je van een functie gebruik maakt is dat een overweging (performance vs efficiency). Het voorkomt in ieder geval dat je op voorhand altijd al een setje getters en setters staat te "boiler platen" omdat je er "misschien ooit nog eens" een getter/setter voor nodig hebt.

Reageren