Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Modern syntax

PHP 8 changed the language a lot: short and safe ways appeared to write what used to take several lines. These constructs show up in any modern code and framework.

The ?-> operator

A regular arrow causes an error when the left side is null. The ?-> operator stops the chain in that case and returns null:

<?php
 
class Address
{
    public function __construct(public string $city) {}
}
 
class User
{
    public function __construct(public ?Address $address = null) {}
}
 
$withAddress = new User(new Address('London'));
$withoutAddress = new User();
 
echo $withAddress->address?->city ?? 'no city', "\n"; // London
echo $withoutAddress->address?->city ?? 'no city';    // no city

Destructuring

An array can be spread into variables in one line:

<?php
 
[$first, $second] = ['tea', 'coffee'];
['name' => $name, 'age' => $age] = ['name' => 'Anna', 'age' => 25];
 
echo $first, ' ', $second, ' ', $name, ' ', $age; // tea coffee Anna 25

Values are swapped the same way: [$a, $b] = [$b, $a]. In a foreach loop it removes the need to access by key:

<?php
 
$points = [[1, 2], [3, 4]];
 
foreach ($points as [$x, $y]) {
    echo $x + $y, ' ';
}

The spread operator

Three dots insert the elements of one array into another:

<?php
 
$defaults = ['theme' => 'light', 'size' => 14];
$custom = ['size' => 16];
 
$settings = [...$defaults, ...$custom];
 
echo json_encode($settings); // {"theme":"light","size":16}

When string keys clash, the value that comes later wins.

Default assignment

The ??= operator assigns a value only if the variable is not set or is null:

<?php
 
$options = ['theme' => 'dark'];
 
$options['theme'] ??= 'light';
$options['size'] ??= 14;
 
echo json_encode($options); // {"theme":"dark","size":14}

Immutable objects

A class with the word readonly makes every property read-only. To "change" an object, a new one is created:

<?php
 
readonly class Money
{
    public function __construct(public int $amount, public string $currency) {}
 
    public function add(int $value): static
    {
        return new static($this->amount + $value, $this->currency);
    }
}
 
$price = new Money(250, 'USD');
$total = $price->add(100);
 
echo $price->amount, ' ', $total->amount; // 250 350

A reference to a function

The form with three dots in parentheses turns a function or a method into a value:

<?php
 
$upper = strtoupper(...);
 
echo implode(', ', array_map($upper, ['php', 'js'])); // PHP, JS

Attributes

An attribute is a label in the code that frameworks and tools read. It is written before a class, a method or a parameter in #[ ]:

<?php
 
#[Attribute]
class Route
{
    public function __construct(public string $path) {}
}
 
class PostController
{
    #[Route('/posts')]
    public function index(): string
    {
        return 'List of posts';
    }
}
 
$method = new ReflectionMethod(PostController::class, 'index');
$route = $method->getAttributes(Route::class)[0]->newInstance();
 
echo $route->path; // /posts

An attribute does nothing by itself — it only stores information that someone reads later.

Common mistake

New syntax requires a new PHP version on the server. readonly classes appeared in 8.2, enumerations and readonly properties in 8.1, named arguments and match in 8.0. Before using a construct, check the version with php -v and state it in composer.json.

Thanks for reading!

Donate to the site — we work hard for you.