Understanding Asymmetric Property Visibility in PHP 8.4

PHP 8.4, released in November 2024, introduces Asymmetric Property Visibility, which allows separate visibility levels for reading and writing class properties, enhancing access control while preserving encapsulation.

What is Asymmetric Property Visibility?

In PHP 8.4, you can now define different visibility levels for reading and writing a property within a class.

Previously, PHP allowed properties to be (public), (protected), or (private), but both reading and writing had the same visibility level. With Asymmetric Property Visibility, you can set separate visibility for getting and setting a property.

A Basic Example

class User {
    public string $name { public get; private set; }

    public function __construct(string $name) {
        $this->name = $name; // Allowed: private setter is used inside the class
    }

    public function changeName(string $newName) {
        $this->name = $newName; // Allowed: inside class
    }
}

$user = new User("Alice");
echo $user->name; // ✅ Allowed: public getter
$user->name = "Bob"; // ❌ Error: Cannot modify, setter is private

Key Takeaways

  • (get) visibility is public, allowing read access from anywhere.
  • (set) visibility is private, so only class methods can modify the property.

Example 2: Preventing Direct Modification of Sensitive Properties

class BankAccount {
    public int $balance { public get; private set; }

    public function __construct(int $initialBalance) {
        $this->balance = $initialBalance;
    }
    public function deposit(int $amount) {
        $this->balance += $amount; // ✅ Allowed: inside class
    }
    public function withdraw(int $amount) {
        if ($amount > $this->balance) {
            throw new Exception("Insufficient funds");
        }
        $this->balance -= $amount; // ✅ Allowed: inside class
    }
}

$account = new BankAccount(1000);
echo $account->balance; // ✅ Allowed: public getter
$account->balance = 500; // ❌ Error: Cannot modify, setter is private

Key Takeaways

  • Prevents unauthorized modifications to ($balance) while allowing controlled updates through class methods.
  • Improves security by ensuring logic (e.g., preventing overdrafts) is always enforced.

Caveats & Considerations

  • This feature only applies to typed properties ((int), (string), (array), etc.). Typed properties are supported since PHP 7.4
  • You must specify a visibility level for both (get) and (set) (e.g., ({ public get; private set; })).
  • Asymmetric visibility cannot be applied to untyped properties.

How Was Asymmetric Property Visibility Achieved Before PHP 8.4?

Before Asymmetric Property Visibility, PHP only allowed single visibility for properties ((public), (protected), or (private)). This meant that if a property was readable, it was also writable unless additional methods were used to restrict modifications.

To achieve similar behavior, developers had to use getter and setter methods manually using Getter & Setter Methods (Manual Encapsulation)

For example:

class User {
    private string $name;

    public function __construct(string $name) {
        $this->name = $name;
    }

    // Public getter method
    public function getName(): string {
        return $this->name;
    }

    // Private setter method (prevents external modification)
    private function setName(string $name): void {
        $this->name = $name;
    }

    public function changeName(string $newName): void {
        $this->setName($newName); // Allowed inside class
    }
}

$user = new User("Alice");

echo $user->getName(); // ✅ Allowed: public getter\
$user->setName("Bob"); // ❌ Error: Cannot access private method\
$user->name = "Bob"; // ❌ Error: Cannot access private property

Problems with the Traditional Approach

  1. More Boilerplate Code
  • Requires explicit getter and setter methods for each property.
  • Increases code duplication when dealing with many properties.

2. Less Readable & Natural Code

  • Instead of ($user->name), you need to call ($user->getName()).
  • Assigning a value (($user->name = “Bob”;)) is replaced by a method (($user->changeName(“Bob”);)).

Why Asymmetric Property Visibility Matters

Asymmetric Property Visibility in PHP 8.4 enhances encapsulation by allowing developers to set different visibility levels for reading and writing a property. This means a property can be publicly readable but privately writable, preventing unintended modifications while still making data accessible. 

Previously, achieving this required workarounds like getter and setter methods, but now it can be done more cleanly and intuitively. This feature improves code maintainability, security, and clarity, making it easier to enforce strict control over property access without extra boilerplate.

Final Thoughts

Before PHP 8.4, getter and setter methods were the only way to enforce asymmetric visibility. While effective, it resulted in verbose and less readable code. With Asymmetric Property Visibility, PHP now provides native support for defining different access levels for reading and writing properties, making property management much cleaner and more intuitive.

Meet Querro! 📈 Embeddable SQL-based Data Analytics in Your App

X