With the release of PHP 8.4 on November 21, 2024, many new features are released. Though every feature deserves its article, one that fascinated me the most is Asymmetric Visibility. Though some programming languages like C# and Swift have had this capability for some time now (as I learned on Reddit), it still excites me that PHP has this now.

What is Visibility?

Anyone familiar with OOPs knows about visibility, aka scopes. Classified in the following three categories

  • Public
  • Private
  • Protected

Public Visibility

In PHP, Public Visibility allows a class's properties and methods to be accessed from anywhere—inside the class, subclasses, and external code. It's the most permissive access level, enabling broad interaction with an object's members.

Private Visibility

Private Visibility restricts access to a class's properties and methods, allowing access only within the same class. They cannot be used by subclasses or external code, ensuring strict encapsulation and control.

Protected Visibility

Protected Visibility allows a class's properties and methods to be accessed within the class and its subclasses. External code cannot access them, promoting controlled inheritance and encapsulation

Let's create an example for better understanding.

namespace App;

class Animal
{
    public string $name;

    private string $species;
}

Now, let's try to access both properties,

$animal = new Animal();

echo $animal->name; // Dog

echo $animal->species; // Error: Cannot access private property App\Animal::$species

As you can see, you can access the name but can not access the species as it is not public.

Requirement for Asymmetric Visibility

Consider the case where you need a property having the ability to read outside the class but not to be written outside the class. Having different visibility when it comes to read and write operations.

Asymmetric Visibility provides that, it provides us with the capability to have different read and write visibility for the same property.

Syntax of Asymmetric Visibility

{read visibility} {set visibility}(set) {propertyType} $variableName;

To implement this, following rules are to be kept in mind.

  • It's only available after PHP 8.4, make sure your PHP version is up to date.
  • Public is default visibility until provided otherwise
  • Type declaration is a must for Asymmetric Visibility implementation
  • When using property hooks, visibility rules also apply to the corresponding get and set methods respectively.
  • The write visibility must be the same as or more restricted than the read visibility.
  • The set (write) visibility always includes the string "(set)" at the end.

Let's update our example.

public private(set) string $species = 'Canine';

// can also be written as 

private(set) string $species = 'Canine';

Now, the read visibility of the property species is set to public, so you can access it from the instance, but the write visibility is private, it can not be written from outside the class. Hence, the name Asymmetric Visibility.

echo $animal->species; // Canine

// this won't give you an error now.