DEV Community

Cover image for What's new in PHP 8 and what does that mean
Josip Opačić
Josip Opačić

Posted on

What's new in PHP 8 and what does that mean

Photo by Larry Li on Unsplash

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, 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 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!

@@Route(Http::POST, '/store/123/item')
class ItemCreateHandler
    public function __invoke() {
        // ...
Enter fullscreen mode Exit fullscreen mode

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]:

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 and here.

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:

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;
Enter fullscreen mode Exit fullscreen mode

... you get the idea. Well, it's a wee bit easier. What does that mean? Here's how it could be written:

class Response {
    public function __construct(
        private int $code,
        private string $body,
        private array $headers,
    ) {}
Enter fullscreen mode Exit fullscreen mode

Neat! The assignment happens before the constructor code is executed. You can absolutely mix constructor promoted properties with standard props (please don't).

There are some limitations, you can check them out here.

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:

switch ($x) {
    case 1:
        $y = 3;
    case 2:
        $y = 4
    case 3: case 4:
        $y = 5;
        throw new \RuntimeException('Not happening, bud');
Enter fullscreen mode Exit fullscreen mode

What does this mean? Well, now we can write it more readably.

$y = match ($x) {
    1 => 3,
    2 => 4,
    3, 4 => 5,
    default => throw new \RuntimeException('Not happening, bud'),
Enter fullscreen mode Exit fullscreen mode

It's important to note the new match expression now returns a value, so it's unnecessary to repeat the assignment throughout your cases.

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:

class Number {
    private int|float $number;

    public function setNumber(int|float $number): void {
        $this->number = $number;

    public function getNumber(): int|float {
        return $this->number;
Enter fullscreen mode Exit fullscreen mode

As you might be familiar with ? to represent nullable, you could also use null:

public function handle(Product|null $product): int
// equals
public function handle(?Product $product): int
Enter fullscreen mode Exit fullscreen mode

For more information about nitty-gritty details and it's limitations, read it's RFC 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:

// Positional arguments
json_encode($data, 0, 512);

// Named arguments
json_encode(value: $data, options: 0, depth: 512);
Enter fullscreen mode Exit fullscreen mode

I'll let you pick which one you like more.

Named arguments allow you to skip default values:

json_encode(value: $data, depth: 256);
Enter fullscreen mode Exit fullscreen mode

You can mix unnamed ones with named ones:

json_encode($data, depth: 256);
Enter fullscreen mode Exit fullscreen mode

But if you wrongly pass an ordered argument after a named one, it will throw an error:

// This code will throw
json_encode(depth: 256, $data);
Enter fullscreen mode Exit fullscreen mode

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!

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 ¯\_(ツ)_/¯

get_class($a) === $a::class;
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (10)

phantas0s profile image
Matthieu Cneude

That's funny. I wrote a lot of PHP in the past, and I follow its development. The language appears more and more weird to me.

I don't see any real value of most of this. It looks just messier. What's the problem of writing a constructor? Especially since you can just use snippets in your editor. Same with switch cases.

Union types would be nice if typing wasn't that... unpredictable without strict types.

Maybe it's just me.

antonmelnyk profile image
Anton Melnyk

Totally agree. Changes are not bad, they're just all over the place and bring nothing valuable.

coderslife_io profile image
Drew Knolton

Seems great at first glance. I was wondering, for the Construction Property Promotion, there is every so often some private setters for validation I will create. Would it be possible to call them at that level or I will need to call them in the constructor like before?

mattschwartz profile image
Matthew Schwartz

Finally adding some of the features I've loved about Python ;)

The annotation feature is huge because parsing docblocks to generate code is awkward and slow. Frameworks like Symfony should see huge performance gains at "build" time or during first load. Also means the PHP runtime can finally throw meaningful warnings or errors before the code executes.

Sloan, the sloth mascot
Comment deleted
michi profile image
Michael Z

Excited to see how writing Laravel code will evolve with all these changes.

messam88 profile image
Mohamed Essam

Really nice and very helpful
Thank you so much

champernet profile image
Timur Iskakov

Helpful post with a lot of explanation.
Thank you.

thinkverse profile image
Kim Hallberg

I feel constructor property promotion and union types are going to be the hot new thing out of all of these new features, the attributes feel so so, could live without them, to be frank.

krishnakakade profile image
krishna kakade

congrats on the first post-Great Article