Read-only public members in PHP

Door AtleX op vrijdag 21 december 2007 09:52 - Reacties (2)
Categorieën: HowTo, PHP, Views: 3.636

Bij Java erger ik me al tijden aan het feit dat je voor elke member/propertie/geef-het-beestje-een-naam van een class een get()-er en eventueel ook nog een set()-er moet schrijven. Imho is het alleen maar nutteloos typewerk, en bij grote classes loopt dat best op. C# pakt het wat dat betreft netter aan:

C#:
1
2
3
4
5
6
private String _foo;
public String Foo
{
    get { return this._foo; }
    set { this._foo = value; }
}



PHP kent sinds versie 5 een aantal zogenaamde magic methods. De bekendste is waarschijnlijk __construct() om de constructor aan te duiden. 2 Van de andere methods, __get() & __set(), zijn veel minder bekender.

__get() dient voor het ophalen van members, en __set() is logischerwijs de setter. Om nu read-only public members te maken hoef je alleen maar je members private te maken (logisch toch? :P) en een __get() methode toe te voegen. Bijvoorbeeld:


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Foo
{
    private $Bar;
    
    public function __construct()
    {
        $this->Bar = "Candy";
    }
    
    public function __get($name)
    {
        if (isSet($this->{$name}))
            return $this->{$name};
        else
            throw new UnknownPropertyException();
    }
}



Als er geprobeerd wordt om een waarde toe te wijzen aan $Bar gaat het fout, en treed er een fatal error op. Bijvoorbeeld:

PHP:
1
2
$foo = new Foo();
$foo->Bar = "0xDEADBEEF";


Dat levert de volgende melding op:
Fatal error: Cannot access private property Foo::$Bar in home/akamsteeg/public_html/test/php/readonly_member.php on line 25


Een nadeel van deze methode is dat PHP niet meer kan weten of je als programmeur zijnde een bestaande member probeert te benaderen. Daarom throw ik in __get() een zelf gedefinieerde UnknownPropertyException. Op die manier kan je de programmeur die je class gebruikt beschermen tegen bijvoorbeeld typefouten, wat hem of haar een hoop debugwerk kan besparen.

Door middel van __set() is het ook nog mogelijk om values te setten, met controle op de waardes. Dit levert nog wel behoorlijk wat typewerk op, want je zal met een switch()-case boompje (nog zo'n nadeel van Java, niet kunnen switchen op Strings) moeten bepalen welke member je gaan setten en welke methode je ter controle moet gebruiken. Ook moet je er dan dus goed aan denken dat als je bovenaan je class een member toevoegt je ook je __set() methode aanpast. Wel is het om consistent te blijven een goed idee om deze methode te gebruiken als je ook gebruik maakt van __get().

Volgende: Merry Christmas 12-'07 Merry Christmas
Volgende: Mijn idee van een PHP framework 12-'07 Mijn idee van een PHP framework

Reacties


Door Tweakers user Vold, maandag 24 december 2007 15:59

Sinds php 5 lijkt php best wel veel op C#... Nu heb ik php 5 al wel een beetje onder de knie, en zou graag de overstap willen maken naar C#, maar ik weet niet zo goed waar ik kan beginnen.
Het liefst heb ik een goed c# boek waar de basics in staan uitgelegd, heb jij daar nog suggesties voor?

Wel mooi en duidelijk artikel heb je iig geschreven, ik gebruik zelf ook al die mogelijkheid, alleen die foutafhandeling nog niet, erg handig! (hopelijk komen er meer..;)!)

Prettige feestdagen,

Door Tweakers user Snake, maandag 31 maart 2008 02:54

En die UnknowPropertyException sharen, is dat mogelijk? :+

Reageren is niet meer mogelijk