PHP: Setters and Getters have died

What are you talking about?PHP 7.

4, which is set to be released in November 21 of this year, has introduced typed properties.

In a nutshell, a typed property will only allow a certain type of variable to be set inside in the Class property.

For example, let’s say we want the Car class to allow any class that implements the CarEngine interface, like GasEngine or ElectricEngine.

As of today, we need one getter and setter for each for this property to force the developer to use only these types,as you saw in the above example.

To avoid meddling with these properties directly, we use the protected keyword.

This means, the properties will be able to be accessed only from within the class methods, or other classes that extend it.

However, if we use typed properties, the Class will only allow that type to be set as a property, killing the purpose of a getter and setter.

We don’t need to use it as protected property, we can just set it as public.

<?phpclass Car{ /** * Car Engine * * @var CarEngine $engine */ public CarEngine $engine; // .

}There are two good things about this:Slims down the Class to the bare functionality methods as it should be.

The developer can access directly to the property, instead of wasting lines for retrieving it and setting it.

Bypasses any method overhead that could incur by using the getter or setter.

Now, let’s use our class.

<?php$car = new SportsCar(new CarEngine, new Wheels);$car->wheels->color = 'red';$car->spoiler = null; // Comes by default but we don't need itif ($car->engine->start()) { $car->lights->on = true;}Let’s compare it to the old way:<?php$car = new SportsCar(new CarEngine, new Wheels);$car->getWheels()->setColor('red');$car->setSpoiler(null); // Comes by default but we don't need itif ($car->getEngine()->start()) { $car->getLights()->setOn(true);}In that example we used only one method call compared to seven.

We basically lowered our overhead by 86%.

This will take a while for applications and frameworks to grasp into, since this means to make some properties public while properly typing them, and killing the getters and setters.

Interfaces dilemmaThere is also another problem, or dilemma, for better wording.

We used the latter examples without an interface, but some classes must use them because they expect them.

Usually some interfaces implement getters and setters to note that it should have an object available to set and retrieve.

I don’t consider this good practice, because these are just what interfaces aren’t intended to solve.

Interfaces are a contract of behaviour, not shape.

<?phpinterface Car { public function getEngine(); public function setEngine(CarEngine $engine); public function startEngine();}Then, why don’t use public properties in interface?.Guess what: Interfaces doesn’t have properties.

If a class that implements an Interface could dispose of a setter and getter for its own typed property, swapping this class for another of the same Interface would be shaky because there is no guarantee the other Class have the same properties declared.

For example, SportsCar uses $engine for its engine, but ElectricCar uses two engines, and they’re saved in $frontEngine and $backEngine.

<?php$sportsCar = new SportsCar;$sportsCar->engine->start(); // true$electricCar = new ElectriCar;$electricCar->engine->start(); // ERROR, the property doesn't existsInstead, we should be doing this:<?phpinterface Car{ public function startEngine();}class ElectricCar implements Car{ protected Engine $frontEngine; protected Engine $backEngine; public function __construct(ElectricEngine $engine) { $this->frontEngine = $engine; $this->backEngine = clone($engine); } public function startEngine() { $this->frontEngine->start(); $this->backEngine->start(); }}$car = new ElectricCar(new ElectricEngine);$car->startEngine();Again, the Interface should be more concerned with its public behaviour rather than having getters and setters for properties, which is good, but that means you couldn’t (and shouldn’t) rely on accessing an object property directly if you want to handle them.

Personally, I would avoid accessing to typed properties on Classes that implement something.

If I swap the Class for another, and I use direct access to a property the new one doesn’t have, code may break, because the whole point of the Interface is to use its methods to handle the functionality of the Class should provide.

With the dawn of the open season for type hinted properties, surely will be some discussion among developers for this.

But if you’re using typed properties for your own class, you should be safe.


. More details

Leave a Reply