Data and Logic Together: Property and Method Visibility in PHP

The ComboMeal constructor in Example 6-12 does a great job of ensuring that a ComboMeal is only given instances of Entree to be its ingredients. But what happens after that? Subsequent code could change the value of the $ingredients property to anything—an array of non-Entrees, a number, or even false.

We prevent this problem by changing the visibility of the properties. Instead of public, we can label them as private or protected. These other visibility settings don’t change what code inside the class can do—it can always read or write its own properties. The private visibility prevents any code outside the class from accessing the property. The protected visibility means that the only code outside the class that can access the property is code in subclasses.

Example 6-13 shows a modified version of the Entree class in which the $name prop­erty is private and the $ingredients property is protected.

Example 6-13. Changing property visibility

class Entree {

private $name;

protected $ingredients = array();

/* Since $name is private, this provides a way to read it */

public function getName() {

return $this->name;

}

public function _ construct($name, $ingredients) {

if (! is_array($ingredients)) {

throw new Exception(‘$ingredients must be an array’);

}

$this->name = $name;

$this->ingredients = $ingredients;

}

public function hasIngredient($ingredient) {

return in_array($ingredient, $this->ingredients);

}

}

Because $name is private in Example 6-13, there is no way to read or change it from code outside Entree. The added getName() method provides a way for non-Entree code to get the value of $name, though. This kind of method is called an accessor. It provides access to a property that would otherwise be forbidden. In this case, the combination of private visibility and an accessor that returns the property value lets any code read the value of $name, but nothing outside of Entree can change $name’s value once it’s been set.

The $ingredients property, on the other hand, is protected, which allows access to $ingredients from subclasses. This ensures that the hasIngredient() method in ComboMeal works properly.

The same visibility settings apply equally to methods as well as properties. Methods marked public may be invoked by any code. Methods marked private may be invoked only by other code inside the same class. Methods marked protected may be invoked only by other code inside the same class or inside subclasses.

Source: Sklar David (2016), Learning PHP: A Gentle Introduction to the Web’s Most Popular Language, O’Reilly Media; 1st edition.

Leave a Reply

Your email address will not be published. Required fields are marked *