Use Asymmetric Property Visibility in PHP 8.4

Use Asymmetric Property Visibility in PHP 8.4

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.

Counter.php

<?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.

Counter.php

<?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

Your email address will not be published.