In een poging de grenzen van php te verkennen, heb ik een methode gevonden om setters en getters “onzichtbaar” te implementeren. Het lijkt in je code net of je de attributen direct aanspreekt, maar in werkelijkheid, kun je er daadwerkelijk validatie aan hangen, iets waar je normaal gesproken een setter of een getter nodig hebt.
Voorbeeld
class Example
{
// Attribuut
public $attribute;
// Setter
public function setAttribute($value)
{
// Validation
$this->attribute = $value;
}
}
$example = new Example();
// Direct
$example->attribute = 1;
// Via setter
$example->setAttribute(1);
Waarom?
Goeie vraag, geen idee, zoals ik al zei, ik was de grenzen aan het verkennen, erg nuttig is het dus niet, maar wel interessant
.
Doel?
Het doel is dus dat je achteraf je validatie / filters op een bepaald attribuut kan toevoegen, zonder dat je daar functies voor aan hoeft te roepen, natuurlijk moet je de setter of de getter wel aanmaken. Om dit te realiseren maak ik gebruik van de magische functies __set en __get, die alleen aangesproken worden wanneer php het betreffende attribuut kan bereiken omdat deze bijvoorbeeld private, protected is of zelfs niet bestaat.
Code!
Hieronder zie je hoe ik de classe geschreven heb.
class AutoGetSet
{
public function __set($key, $value)
{
// De naam van de set methode
$method = 'set'.ucfirst($key);
try
{
// Roep de functie aan
call_user_func(
array($this, $method),
$value
);
}
catch ( InvalidFunctionException $ex )
{
throw new Exception('No setter defined for '.$key.'.');
}
}
public function __get($key)
{
// De naam van de set
$method = 'get'.ucfirst($key);
try
{
// Roep de functie aan en return het resultaat
return call_user_func(
array($this, $method)
);
}
catch ( InvalidFunctionException $ex )
{
throw new Exception('No setter defined for '.$key.'.');
}
}
// Als er een functie aangeroepen wordt die niet bestaat, gooi dan een Exception.
public function __call($function, $args)
{
throw new InvalidFunctionException('Function '.$function.' does not exist in '.__CLASS__.'.');
}
}
Om te zorgen dat de set en getters aangesproken worden, moet je het attribuut protected maken.
Conclusie
Het is me dus uiteindelijk gelukt om de setters en getters “onzichtbaar” te maken. Hoewel ik het zelf niet gebruik vond ik het toch wel een geslaagde test.
Nog wat voorbeelden
Zonder setter en getter zal de code er zo uitzien en werkt hij gewoon zoals je van php gewend bent.
class Example
{
public $attribute;
}
$example = new Example();
$example->attribute = 'Test';
echo $example->attribute;
Vervolgens kun je de setter en de getter toevoegen. Let op het attribuut is protected geworden.
class Example extends AutoGetSet
{
// Let op protected!
protected $attribute;
// Setter
public function setAttribute($value)
{
echo 'SET attribute to '.$value;
$this->attribute = $value;
}
// Getter
public function getAttribute()
{
echo 'GET attribute';
return $this->attribute;
}
}
$example = new Example();
$example->attribute = 'Test';
echo $example->attribute;
Als je nu de output bekijkt zul je zien dat de setter en de getter automatisch aangeroepen worden.
Ik ben benieuwd wat vindt jij ervan? Nog leuke ideeen voor situaties waarbij dit bruikbaar is?
Ben nog niet zó ver met php, maar iig succes met je framework!
Ik wou dat ik een nuttige reactie kon plaatsen, maar helaas (nog) niet.
Gr, Marinus (Creadion)
Yes! Het eerste commentaar!
Is het wel begrijpelijk om te lezen? Als je ideeën hebt voor artikelen, dan roep je maar
Hoi Reen,
kwam op PCH een link naar je site tegen.
Opzich wel grappig idee dit, nog niet echt bij stilgestaan dat het kon.
Zelf ook nog niet echt nodig gehad maar kan inderdaad handig zijn bij een framework. Ben laatst trouwens zelf aan het experimenteren geweest met het zend framework, ook wel grappig.
Heb het maar wel rustig gehouden, dus wel m’n eigen pagina systeem gebouwd. Maar de Zend_DB en Zend_Validator kunnen af en toe wel handig zijn.
Misschien trouwens ook wel grappig om je website wat te pimpen, dus ff een niet-standaard-template en een syntax highlighter bij de code blokken voor betere leesbaarheid.
Hey Nino,
Thanks voor je reply, je hebt gelijk wat betreft het pimpen, de code is echt niet leesbaar.
In hoeverre maak je gebruik van Zend_Db, schrijf je nog wel zelf je query’ s?
Check je!
De select queries schijf ik zelf, voor de rest roep ik de betreffende functie aan zoals ook werd geadviseerd in de documentatie.