Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Современный синтаксис

PHP 8 сильно изменил язык: появились короткие и безопасные способы записать то, что раньше занимало несколько строк. Эти конструкции встречаются в любом современном коде и фреймворках.

Оператор ?->

Обычная стрелка вызывает ошибку, если слева null. Оператор ?-> в этом случае останавливает цепочку и возвращает null:

<?php
 
class Address
{
    public function __construct(public string $city) {}
}
 
class User
{
    public function __construct(public ?Address $address = null) {}
}
 
$withAddress = new User(new Address('Казань'));
$withoutAddress = new User();
 
echo $withAddress->address?->city ?? 'город не указан', "\n";    // Казань
echo $withoutAddress->address?->city ?? 'город не указан';       // город не указан

Деструктуризация

Массив можно разложить по переменным одной строкой:

<?php
 
[$first, $second] = ['чай', 'кофе'];
['name' => $name, 'age' => $age] = ['name' => 'Анна', 'age' => 25];
 
echo $first, ' ', $second, ' ', $name, ' ', $age; // чай кофе Анна 25

Так же меняют значения местами: [$a, $b] = [$b, $a]. В цикле foreach это избавляет от обращений по ключу:

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

Оператор распаковки

Три точки вставляют элементы одного массива в другой:

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

При совпадении строковых ключей побеждает значение, которое стоит позже.

Присваивание по умолчанию

Оператор ??= присваивает значение, только если переменная не задана или равна null:

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

Неизменяемые объекты

Класс со словом readonly делает все свойства доступными только для чтения. Чтобы «изменить» объект, создают новый:

<?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, 'RUB');
$total = $price->add(100);
 
echo $price->amount, ' ', $total->amount; // 250 350

Ссылка на функцию

Запись с тремя точками в скобках превращает функцию или метод в значение:

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

Атрибуты

Атрибут — это метка в коде, которую читают фреймворки и инструменты. Его пишут перед классом, методом или параметром в #[ ]:

<?php
 
#[Attribute]
class Route
{
    public function __construct(public string $path) {}
}
 
class PostController
{
    #[Route('/posts')]
    public function index(): string
    {
        return 'Список статей';
    }
}
 
$method = new ReflectionMethod(PostController::class, 'index');
$route = $method->getAttributes(Route::class)[0]->newInstance();
 
echo $route->path; // /posts

Сам по себе атрибут ничего не делает — он лишь хранит сведения, которые кто-то потом прочитает.

Частая ошибка

Новый синтаксис требует новой версии PHP на сервере. readonly-классы появились в 8.2, перечисления и readonly-свойства — в 8.1, именованные аргументы и match — в 8.0. Прежде чем использовать конструкцию, проверьте версию командой php -v и укажите её в composer.json.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.