Since PHP 8.4, we can use asymmetric property visibility, which enables class properties to define their visibility (public, protected, or private) separately for reading and writing operations. It can minimize the need for redundant getter methods to expose a property's value while preventing external modification.
In the provided code, the Counter
class manages count with methods to read and modify its value. The getCount
method provides read-only access to the current count, while the increment
and decrement
methods allow increasing or decreasing the count by a specified value.
<?php
class Counter
{
private int $count = 0;
public function getCount(): int
{
return $this->count;
}
public function increment(int $value = 1): void
{
$this->count += $value;
}
public function decrement(int $value = 1): void
{
$this->count -= $value;
}
}
<?php
require __DIR__.'/Counter.php';
$counter = new Counter();
$counter->increment(5);
$counter->decrement();
echo $counter->getCount(); // 4
Since PHP 8.4, we can rewrite code using asymmetric property visibility. It allows the property to have public visibility for reading and private visibility for writing. This eliminates the need for the getter method while still restricting direct modification of property from outside the class.
<?php
class Counter
{
public private(set) int $count = 0;
public function increment(int $value = 1): void
{
$this->count += $value;
}
public function decrement(int $value = 1): void
{
$this->count -= $value;
}
}
<?php
require __DIR__.'/Counter.php';
$counter = new Counter();
$counter->increment(5);
$counter->decrement();
echo $counter->count; // 4
There are some notes for asymmetric property visibility.
Constructor property promotion
Asymmetric property visibility also works with constructor property promotion:
<?php
class Counter
{
public function __construct(public private(set) int $count = 0)
{
}
// ...
}
Not weaker than set visibility
The set
visibility must be the same as, or more restrictive than, the get
visibility:
<?php
class Counter
{
public private(set) int $count = 0; // OK
public protected(set) int $countLimit; // OK
protected protected(set) int $maxCount; // OK
protected public(set) int $minCount; // Error
// ...
}
Fatal error: Visibility of property Counter::$defaultCount must not be weaker than set visibility in ...
Shorthand syntax
Since public properties that are writable only within a private or protected context are the most common use cases for asymmetric visibility, a shorthand syntax is also available:
<?php
class Counter
{
private(set) int $count = 0; // same as public private(set)
protected(set) int $countLimit; // same as public protected(set)
// ...
}
Leave a Comment
Cancel reply