What's new in PHP 8 and what does that mean
Tags: php, php8, news, webdev
Published: 2020-07-24 22:35:54

---
title: What's new in PHP 8 and what does that mean
published: true
description: A quick run-down of new features in PHP8
tags: php, php8, news, webdev
cover_image: https://jopacicdev-public.s3.amazonaws.com/larry-li-uZqJVqwFxMQ-unsplash.jpg
---

*<span>Photo by <a href="https://unsplash.com/@larryli?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Larry Li</a> on <a href="https://unsplash.com/s/photos/elephant?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>*

The official General Availability date for PHP 8 is November 26th, 2020 which will be when all the new and shiny features are stable and available. While this article is being written during the [Alpha phase](https://wiki.php.net/todo/php80), and before the Feature Freeze, the content may be updated. Here's a rundown of the most interesting new features and what do they mean for us!

## Attributes
Attributes are, hands down, the biggest addition to PHP. Attributes help add metadata to functions/parameters/classes/methods/constants/properties etc -- what was previously simulated via docblocks, and then parsed elsewhere. Attributes are now first-class citizens in PHP, and can be accessed programmatically!

```php
@@Route(Http::POST, '/store/123/item')
class ItemCreateHandler
{
    public function __invoke() {
        // ...
    }
}
```

It's notation is still unfolding -- going from `<<FooAttribute>>` to `@@FooAttribute`, and Derick Rethans challenging the whole thing with a simple 'Are we reaaaaaly sure?' question, proposing Rust-like `#[FooAttribute]`:
{% twitter 1285912223639130114 %}

There are signs that there might even be a RFC during the Feature Freeze period. Either way, there's no denying that attributes are a  welcomed feature! If you'd like to read an in-depth analysis, check [here](https://stitcher.io/blog/attributes-in-php-8) and [here](https://php.watch/versions/8.0/attributes).

## Constructor property promotion
Simple argument-to-property assignment, your days are numbered! There were quite some times that all of us written (almost) the same constructor over and over:

```php
class Response {
    private int $code;
    private string $body;
    private array $headers;

    public function __construct(int $code, string $body, array $headers) {
        $this->code = $code;
        $this->body = $body;
        $this->headers = $headers;
    }
}
```
... you get the idea. Well, it's a wee bit easier. What does that mean? Here's how it could be written:

```php
class Response {
    public function __construct(
        private int $code,
        private string $body,
        private array $headers,
    ) {}
}
```
Neat! The assignment happens before the constructor code is executed. You can absolutely mix constructor promoted properties with standard props (please don't).

{% twitter 1283385677804183554 %}

There are some limitations, you can check them out [here](https://php.watch/versions/8.0/constructor-property-promotion).

## `match` expression
How many times have you written line-intensive `switch` expressions, just to end up with a kraken devouring your viewport? Here's a good example:

```php
switch ($x) {
    case 1:
        $y = 3;
        break;
    case 2:
        $y = 4
        break;
    case 3: case 4:
        $y = 5;
        break;
    ...
    default:
        throw new \RuntimeException('Not happening, bud');
} 
```
What does this mean? Well, now we can write it more readably.

```php
$y = match ($x) {
    1 => 3,
    2 => 4,
    3, 4 => 5,
    ...
    default => throw new \RuntimeException('Not happening, bud'),
}
```
It's important to note the new `match` expression now returns a value, so it's unnecessary to repeat the assignment throughout your `case`s.

Probably inspired by ES6 to look a bit more modern each matching case contains only one expression, and also a `break` is implicit - so the condition won't just fall through as in `switch`.

## Union Types

The next feature should come in handy since PHP is a dynamically typed language. Union types allow you to specify 2 or more acceptable types for an argument or return type. PHP already supports two special union types (`Type` or `null` using the special `?Type` syntax; and `array` or `Traversable` using the `iterable` type).
Now, instead of handling types with phpdoc annotations, the following could be used:
```php
class Number {
    private int|float $number;
 
    public function setNumber(int|float $number): void {
        $this->number = $number;
    }
 
    public function getNumber(): int|float {
        return $this->number;
    }
}
```
As you might be familiar with `?` to represent `nullable`, you could also use `null`:
```php
public function handle(Product|null $product): int
// equals
public function handle(?Product $product): int
```
For more information about nitty-gritty details and it's limitations, read it's [RFC](https://wiki.php.net/rfc/union_types_v2) by Nikita Popov.

## Named Arguments
Named arguments allow passing arguments to a function based on the parameter name, rather than the parameter position. Here's a quick example:
```php
// Positional arguments
json_encode($data, 0, 512);

// Named arguments
json_encode(value: $data, options: 0, depth: 512);
```
I'll let you pick which one you like more.

Named arguments allow you to skip default values:
```php
json_encode(value: $data, depth: 256);
```
You can mix unnamed ones with named ones:
```php
json_encode($data, depth: 256);
```
But if you wrongly pass an ordered argument after a named one, it will throw an error:
```php
// This code will throw
json_encode(depth: 256, $data);
```
There is more to it, such as how you can enrich your DTOs or VOs with it using spread operator, how you can use Named Arguments with Attributes, etc -- I strongly suggest that you read and enjoy the [RFC](https://wiki.php.net/rfc/named_params)!

## Use `::class` on objects
How many times have you thought "ow wouldn't it be nice if I could `$a::class`..."? Well, now you can. It accomplishes the same thing as `get_class`, but I prefer it ¯\\\_(ツ)_/¯

```php
get_class($a) === $a::class;
```

Be aware that it will trigger a fatal error on PHP versions lower than 8; and that non-objects cannot use the `::class` notation.

## What does this mean
The community welcomes most of the changes -- (see: Attributes notation as an exception), but I have a feeling that the new version brings in good change. The way we write PHP code is getting a facelift!