Voor mijn website ben ik bezig met een rechtensysteem, waarbij ik een array genereer met rechtendata uit mijn database.
Dit systeem werkt met een Rights-class met o.a de method getRights(). Deze roep ik nu aan in de constructor zodat automatisch de rechten-array geladen wordt bij het instancieren van class met:
<?php
$rights = new Rights();
?>
Nu vroeg ik me af of dit een goed idee is, en of het misschien toch beter is om gewoon de getRights() aan te roepen nadat de class geinstancieerd wordt i.p.v. de constructor te gebruiken. Dus:
<?php
$rights = new Rights();
$rights->getRights();
?>
Mijn class is (versimpeld) als volgt:
<?php
class Rights{
private $rights;
public function __construct() {
$this->getRights();
}
private function getRights() {
// maak hier de array met de rechten die je returned
return $this->rights;
}
}
?>
@Erik: In jouw voorbeeld haal je de rechten toch op met $rights->getRights(), en dus los van de constructor?
@Remco: Er zijn in werkelijkheid nog meer methods binnen de rights-class, zoals checkRights(). Dan is het toch vrij normaal om dit op te slaan in een Rights-class?
Eerst maak je de property $rights private, en vervolgens maak je hier een getter voor, die tevens private is, en alleen bij object creatie aangeroepen wordt? :/. Waar krijgt $rights zijn initiële waarde? Wat doe je nog meer met dit object/deze class (zijn dit alle methoden?) en hoe zet je deze objecten in zodat ze (inderdaad) een meerwaarde hebben ten opzichte van een normaal array?
Als ik zoiets doe:
<?php
$rights = new Rights();
?>
Dan zou ik in eerste instantie verwachten dat $rights een referentie is naar het object (en dit is ook wat je terugkrijgt).
Als je het mij vraagt mis je een stap, dit:
<?php
// maak hier de array met de rechten die je returned
?>
Zou je in een aparte methode kunnen onderbrengen. Die je al dan niet bij creatie aanroept, of apart.
Bijvoorbeeld dus als volgt:
<?php
class Rights
{
protected $rights; // gebruik bij voorkeur protected i.p.v. private zodat je classes kunt extenden
public function __construct() {
$this->rights = false; // init op een "ongeinitialiseerde" waarde, of je laat deze NULL
}
public function init($args) {
$this->rights = array(); // voor als $args verder niets oplevert
// verdere initialisatie op grond van $args
return $this; // voor method chaining
}
public function get() {
if ($this->rights === false) { // of NULL, als je deze bij creatie niet initialiseert op false
throw new Exception('rights was not properly initialized');
}
return $this->rights;
}
}
$r = new Rights();
$rights = $r->init(array('hoi' => 'pipeloi'))->get();
var_dump($rights);
?>
EDIT: bij initialisatie-bij-creatie geef je $args door aan je constructor, en zou je de init() methode protected kunnen maken omdat je deze toch enkel "intern" aanroept.
Ik ben zelf meer van een class mag maar 1 taak hebben.
Dus als jouw Rights class de 'manager' is om dingen te checken dan zou ik via de constructor een class meegeven welke de rechten ophaalt en in je getRights iets doen van $this->rightsLoader->getRights();. En die rightsloader haalt dan de dingen op. Het is ook maar hoe ver je wilt gaan hoor.
Maar om basaal antwoord te geven:
- Dingen die je altijd nodig hebt roep je direct in de constructor op
- Andere dingen doe je pas als de methode wordt aangeroepen.
Maar (invulling) ik zou wel gaan kijken of meer 'separation of concerns' kan toepassen.
Hoever wil je gaan in OOP is vaak de vraag. Ben zelf geen keiharde pro erin, maar het is een stuk beter dan de procedurele meuk die ik eerst had. ;-)
Ik ga zeker eens kijken naar Thomas zijn idee, en de constructor niet standaard de rechtenstructuur laten ophalen. Volgens mij gebeurt dit namelijk steeds opnieuw als je een method aanroept.
Volgens mij moet je het nog abstracter maken, maar dat is een keuze:
a. Wil je daadwerkelijk rechten doorgeven? Hier, alsjeblieft, heb je mijn toegangspas.
b. Of wil je rechten controleren? Heb jij een roze of blauw toegangspasje met de juiste geldigheidsdatum?
In het tweede geval is het logischer een methode hasRights() toe te voegen die true of false retourneert. Zo ontkoppel je de boel. Hoe die rechten verder werken en waar ze vandaan komen is voor de controle niet relevant.
Als je een class Rights hebt die alle rechten cadeau doet met een getRights(), dan is het eigenlijk slechts een container. En dat brengt ons dan bij punt twee: het is slechts een datamodel, waaraan je voor het gebruik van de data misschien nog één of meer controllers moet toevoegen. Bijvoorbeeld een RightsManager of een meer dedicated RightsReader, RightsWriter, RightsRevoker, enzovoort, enzovoort.
In het tweede geval is het logischer een methode hasRights() toe te voegen die true of false retourneert. Zo ontkoppel je de boel. Hoe die rechten verder werken en waar
Mja en in dat geval kun je je ook afvragen of je wel objecten zou moeten bakken omdat deze verder toch niet echt een state hebben, je zou in dat geval ook kunnen volstaan met een static helper class?
<?php
if (Authorization::isAllowed($grantedRights, $requiredRights)) {
// do stuff
}
?>
[quote="Ward van der Put op 23/02/2016 16:52:27"]
In het tweede geval is het logischer een methode hasRights() toe te voegen die true of false retourneert. Zo ontkoppel je de boel. Hoe die rechten verder werken en waar
Mja en in dat geval kun je je ook afvragen of je wel objecten zou moeten bakken omdat deze verder toch niet echt een state hebben, je zou in dat geval ook kunnen volstaan met een static helper class?
<?php
if (Authorization::isAllowed($grantedRights, $requiredRights)) {
// do stuff
}
?>
[/quote]
Het gaat een beetje off-topic, maar waarom zou een User niet zelf mogen weten of het voldoende rechten heeft? $user->isAllowed($requiredRights)
Mja en in dat geval kun je je ook afvragen of je wel objecten zou moeten bakken omdat deze verder toch niet echt een state hebben, je zou in dat geval ook kunnen volstaan met een static helper class?
<?php
if (Authorization::isAllowed($grantedRights, $requiredRights)) {
// do stuff
}
?>
Dat kan ook, maar dan mis je misschien nog een onderdeel ... een class Rights die definieert hoe een collectie rechten eruit ziet. ;)