Snazzier parameters in PHP 8

Language changes aren’t always the most spectacular, but the newer things we can do with parameters in PHP are incredible! PHP 8.0 was released over a year ago, and 8.1 dropped last Thanksgiving. Still, these two versions represent less than 10% of sites today.

Some of the newer features in PHP warrant additional attention.

Readonly properties

Some older projects I’ve worked on made heavy use of objects that were meant to be immutable. You could create an object and read from it at will, but changing the internal state of the object was impossible. This came in handy for video wrappers and some other WordPress-related functionality.

Unfortunately, creating readonly properties in older versions of PHP was quite wordy. You need to first mark the properties as private then create an explicit getter/setter pair for them, with the setter throwing an error.

In some cases, you could create a specific function for each property. Often, my team would fall back on PHP’s magic __set() method:

public function __get(string $name)
{
  if (isset($this->{$name})) {
    return $name;
  }
}

public function __set(string $name, $value)
{
  throw new Exception('Properties are read-only!');
}

Promoted properties

This change is effectively just updated syntax. In modern PHP, you can define properties – and assign them to local variables within your object – directly from the constructor.

In older PHP code, property definition required at least 3 lines of code for every property. First was the declaration, then the parameter in the constructor, and finally assignment to an internal variable:

class Video
{
  private string $id;
  private string $name;
  private string $oembed_url;

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

Snazzier PHP

Modern PHP is so much more elegant!

As of PHP 8.0 we can pull property declaration and assignment into the constructor. As of PHP 8.1 we can also make these promoted properties read-only.

These two changes alone would turn legacy code like the following:

class Video
{
  private string $id;
  private string $name;
  private string $oembed_url;

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

  public function __get(string $name)
  {
    if (isset($this->{$name})) {
      return $name;
    }
  }

  public function __set(string $name, $value)
  {
    throw new Exception('Properties are read-only!');
  }
}

Into a far more elegant form:

class Video
{
  public function __construct(
    public readonly string $id,
    public readonly string $name,
    public readonly string $oembed_url
  )
  {}
}

The PHP we write in 2022 doesn’t look much like what we were writing in 2012 at all. The language continues growing, developing, and we all continue to learn from our experience to build a better system. These are just a few of the most recent changes the language has implemented.

I can’t wait to dive in deeper to some of the more advanced features!

#