Deceptively, the word visibility has nothing to do with application security! Instead it is simply a mechanism to control the use of your code. It can be used to steer an inexperienced developer away from the public use of methods that should only be called inside the class definition.
public, protected, or private keyword in front of any property or method definition. You can label properties as protected or private to enforce access only through public getters and setters.Base class is defined with a protected property $id. In order to access this property, the getId() and setId() public methods are defined. The protected method generateRandId() can be used internally, and is inherited in the Customer child class. This method cannot be called directly outside of class definitions. Note the use of the new PHP 7 random_bytes() function to create a random ID.class Base
{
protected $id;
private $key = 12345;
public function getId()
{
return $this->id;
}
public function setId()
{
$this->id = $this->generateRandId();
}
protected function generateRandId()
{
return unpack('H*', random_bytes(8))[1];
}
}
class Customer extends Base
{
protected $name;
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
}private to prevent it from being inherited or visible from outside the class definition. This is a good way to create a class as a singleton.Registry, of which there can only be one instance. Because the constructor is marked as private, the only way an instance can be created is through the static method getInstance():class Registry
{
protected static $instance = NULL;
protected $registry = array();
private function __construct()
{
// nobody can create an instance of this class
}
public static function getInstance()
{
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
public function __get($key)
{
return $this->registry[$key] ?? NULL;
}
public function __set($key, $value)
{
$this->registry[$key] = $value;
}
}public. As of PHP 7.1, you can declare class constants to be protected or private. In the following example, the TEST_WHOLE_WORLD class constant behaves exactly as in PHP 5. The next two constants, TEST_INHERITED and TEST_LOCAL, follow the same rules as any protected or private property or method:class Test
{
public const TEST_WHOLE_WORLD = 'visible.everywhere';
// NOTE: only works in PHP 7.1 and above
protected const TEST_INHERITED = 'visible.in.child.classes';
// NOTE: only works in PHP 7.1 and above
private const TEST_LOCAL= 'local.to.class.Test.only';
public static function getTestInherited()
{
return static::TEST_INHERITED;
}
public static function getTestLocal()
{
return static::TEST_LOCAL;
}
}Create a file chap_04_basic_visibility.php and define two classes: Base and Customer. Next, write code to create instances of each:
$base = new Base(); $customer = new Customer();
Notice that the following code works OK, and is in fact considered the best practice:
$customer->setId();
$customer->setName('Test');
echo 'Welcome ' . $customer->getName() . PHP_EOL;
echo 'Your new ID number is: ' . $customer->getId() . PHP_EOL;Even though $id is protected, the corresponding methods, getId() and setId(), are both public, and therefore accessible from outside the class definition. Here is the output:

The following lines of code will not work, however, as private and protected properties are not accessible from outside the class definition:
echo 'Key (does not work): ' . $base->key; echo 'Key (does not work): ' . $customer->key; echo 'Name (does not work): ' . $customer->name; echo 'Random ID (does not work): ' . $customer->generateRandId();
The following output shows the expected errors:

For more information on getters and setters, see the recipe in this chapter entitled Using getters and setters. For more information on PHP 7.1 class constant visibility settings, please see https://wiki.php.net/rfc/class_const_visibility.