PHP 7 Object Properties Type Safety with Setters and Getters

PHP 7 introduces scalar type definitions: your function parameters can be of a given type, and function return type declarations ensuring your function will return results of a given data type. This can increase your code quality by enforcing a specific behaviour of your code, almost similar to how a strongly typed language does. However, PHP does not yet support variable or property data types – leaving the possibility of variables and properties to be unpredictably converted from one type to another within type safe functions. Below is a technique that enables you to guarantee object properties will always be of a given type.

Setters and getters, or mutators and accessors, are methods that augment storing or retrieving object property values without accessing them directly. Benefits of using setters and getters are described in this StackOverflow post.

By using setters and getters, when accessing object properties internally or externally to a class, coupled with function parameter data types and function return types you can guarantee these properties will always be of a given type – and thus increase predictability.

Example product class:

class Product { private $price; private $name; function setPrice(int $price) { $this->price = $price; } function getPrice() : int { return $this->price; } private function setName(string $name) { $this->name = $name; } function getName() : string { return $this->name; } function __construct(int $price, string $name) { $this->setPrice($price); $this->setName($name); } }

In this example, the setPrice method will only allow for an integer to be set (see declare strict types for details about type casting from float) for price. The getPrice method will always return a value of the same type. Similarly the $name value will always be set and returned as a string by its own setter and getter. If variable price is not initialised with an integer (new Product(1, “name”))->getPrice() will throw a TypeError exception, and if set to a correct value it will always return an integer.

By contrast, setting the price value directly within the class, enables potential mis-use and loss of data type safety. I.e.:

function __construct(...) { $this->price = $price . ",00"; // Or any other operation that will convert the value from the expected type. }

will convert your value to a string. Later, when accessing the property directly for an operation:

function sellOneItem() { $this->price = $this->price - 1; }

The value will be typecasted to 0 and the set to -1.

To avoid this type of unexpected behaviour use setters and getters when accessing properties either internally or externally coupled with type hinting and function return types.