Bij het doorspitten van verschillende PHP OOP-projecten viel me op dat er twee stijlen in omloop zijn voor het declareren van een array in een klasse.

Sommigen declareren direct een array in de class properties:

<?php
class FooBar
{
    private $foo = array();
    private $bar = array();

    // <...>
}
?>

Anderen bewaren het voor de constructor of stellen het uit tot een setter wordt aangeroepen, schematisch:

<?php
class FooBar
{
    private $foo;
    private $bar;

    public function __construct()
    {
        $this->foo = array();
        // <...>
    }

    public function setBar($params)
    {
        $this->bar = array();
        // <...>
    }
}
?>

Wat zijn eigenlijk de voor- of nadelen van beide stijlen? En geldt hiervoor een best practice?
Als het om een array gaat declareer ik het al in de class properties. Zodat het altijd een array is en de set nog niet gedaan hebt.

En ik set variabelen altijd via een setter dus niet via de construct, zo voorkom je dubbele code, stel ik wil een directory setten dan controlleer ik eerst of de directory bestaat en anders maak ik hem aan. Als ik dat al in de contructor zou doen en via een setter dan krijg je dubbele code. Daarom set ik altijd alles via een setter en die roep ik aan in de constructor (dit geld ook voor de getters).


<?php
	class FooBar {
		private $foo;
		private $bar;

		public function __construct($foo, $bar) {
			$this->setFoo($foo);
			$this->setBar($bar);
		}

		public function setFoo($foo) {
			$this->foo = $foo;
			
			return $this;
		}

		public function getFoo() {
			return $this->foo;
		}

		public function setBar($bar) {
			$this->bar = $bar;

			return $this;
		}

		public function getBar() {
			return $this->bar;
		}
	}
?>
Metal Hertog Jan op 17/01/2014 11:55:08

Als het om een array gaat declareer ik het al in de class properties. Zodat het altijd een array is en de set nog niet gedaan hebt.

Maar dat garandeert niet dat de property een array blijft, want elders zou een ander datatype kunnen worden geset. Dan kun je toch beter setFoo(array $foo) gebruiken?

<?php
class FooBar
{
    private $foo;

    public function __construct(array $foo)
    {
        $this->setFoo($foo);
    }

    private function setFoo(array $foo)
    {
        $this->foo = $foo;
        return $this;
    }
}
?>

Ja klopt, was ook maar een voorbeeldje. Normaal gesproken doe ik in de setter $this->foo = (array) $foo. En soms gooi ik ook nog wel eens een exception als ik echt een een array of dergelijke verwacht.
In echte stricte OO talen is het niet mogelijk op defaults values op property niveau in te stellen. Je hebt hiervoor de constructor nodig, die ook eigenlijk als taak heeft dit te doen. In PHP kun je het dus ook op property niveau doen.

Welke beter is? Geen van beide (of allebei, net hoe positief je in het leven staan ;) ). Er is geen verschil tussen beide.

Op setter niveau declareren lijkt mij vrij nutteloos.
Ward van der Put op 17/01/2014 12:04:23

[quote="Metal Hertog Jan op 17/01/2014 11:55:08"]
Als het om een array gaat declareer ik het al in de class properties. Zodat het altijd een array is en de set nog niet gedaan hebt.

Maar dat garandeert niet dat de property een array blijft, want elders zou een ander datatype kunnen worden geset. Dan kun je toch beter setFoo(array $foo) gebruiken?
[/quote]
Theoretisch heb je gelijk, maar in mijn ogen heb je dan een serieuze fout in je class. Je class is als geheel verantwoordelijk voor zijn eigen properties en daarmee moet je binnen een class ervanuit kunnen gaan dat als een property een array moet zijn het dat dus altijd ook is. Binnen een class zou je wat mij betreft niet overal hoeven af te dwingen danwel te checken dat een private property is wat het moet zijn (waarmee ik dus ook maar weer eens impliciet aangeef waarom je bij mijn geen protected en public properties aantreft). Wat betreft declareren ga ik dan ook met Hertog Jan (maar ben ik het ook eens met Wouter dat het een niet per definitie beter is dan het ander).

@Erwin H, wat is er fout aan "typehinting" van een setter?

Wanneer je wilt afdwingen dat een property wordt geset zoals de betreffende class verreisd, gebruik je typehinting (in dit geval is het array, ook zal dit vaak een verwijzing zijn naar een interface, en bij gebrek hiervan naar een class zelf), naar mijn mening is dit absoluut niet slecht maar juist goed, daar er wordt voorkomen dat de properties verkeerde waarden hebben.

Je kunt in een setter of constructor trouwens toch alleen typehinten op een array of object (en niet op een string of int)? Correct?
allright... just checking... wel vreemd eigenlijk dat je niet kunt typehinten op een string of int...
Local Dev op 18/01/2014 00:08:32

@Erwin H, wat is er fout aan "typehinting" van een setter?

Niets mis met het typehinten van een setter. Zeker niet als de setter public of protected is. Waar het mij om gaat is dat binnen de class je verder niet meer zou moeten hoeven checken dat het een array is. De setter (of constructor, of definitie) moet bepalen dat het een array is en vervolgens mag je overal in de class ervanuit kunnen gaan dat het ook daadwerkelijk een array is. Check alleen alles wat van buiten komt, niet wat van binnen komt.

Reageren