PHP 8

Денис Васишак, Студия "Флаг"

Union types (RFC)


                    public function foo(Foo|Bar $input): int|float;
                

void не может использваться как часть union types, т.к. void означает "не возвращает ничего". Более того, nullable unions могут быть написаны используя |null или ?


                    public function foo(Foo|null $foo): void;

                    public function bar(?Bar $bar): void;
                

Именованные аргументы (RFC)

Именованные аргументы позволяют передавать значения в функцию указывая имя значения. Не обязательно соблюдать порядок объявления и также можно пропускать необязательные параметры


                function foo(string $a, string $b, ?string $c = null, ?string $d = null)

                foo(
                    b: 'value b',
                    a: 'value a',
                    d: 'value d',
                );
            

Атрибуты (RFC)


                class PostsController
                {
                    #[Route("/api/posts/{id}", methods: ["GET"])]
                    public function get($id) { /* ... */ }
                }
            

Выражение Match (RFC)


                echo match (8.0) {
                  '8.0' => "О нет!",
                  8.0 => "То, что я и ожидал",
                };
                //> То, что я и ожидал
            
  • Match — это выражение, его результат может быть сохранён в переменной или возвращён.
  • Условия match поддерживают только однострочные выражения, для которых не требуется управляющая конструкция break;.
  • Выражение match использует строгое сравнение.

Оператор Nullsafe (RFC)


                //PHP 7.4
                $country =  null;
                if ($session !== null) {
                  $user = $session->user;
                  if ($user !== null) {
                    $address = $user->getAddress();
                    if ($address !== null) {
                      $country = $address->country;
                    }
                  }
                }
            

                //Laravel
                $country = optional(optional(optional($session)->user)->getAddress())->country;
            

                //PHP 8
                $country = $session?->user?->getAddress()?->country;
            

Объявление свойств в конструкторе (RFC)


                class Point {
                  public float $x;
                  public float $y;
                  public float $z;

                  public function __construct(float $x, float $y, float $z) {
                    $this->x = $x;
                    $this->y = $y;
                    $this->z = $z;
                  }
                }
            

                class Point {
                  public function __construct(
                    public float $x,
                    public float $y,
                    public float $z,
                  ) {}
                }
            

Улучшенное сравнение строк и чисел (RFC)


                //PHP 7.4
                0 == 'foobar' // true
            

                //PHP 8
                0 == 'foobar' // false
            

При сравнении с числовой строкой PHP 8 использует сравнение чисел. В противном случае число преобразуется в строку и используется сравнение строк.

JIT (RFC)

Возвращаемый тип static (RFC)


                class Foo
                {
                    public function test(): static
                    {
                        return new static();
                    }
                }
            

Выражение Throw (RFC)


                $triggerError = fn () => throw new MyError();

                $foo = $bar['offset'] ?? throw new OffsetDoesNotExist('offset');
            

Weak map (RFC)

Слабые карты (weak maps) позволяют создавать связи между объектами и произвольными значениями (как и SplObjectStorage), при этом объекты, используемые в качестве ключей, не защищаются от сборщика мусора. Если сборщик уничтожает такой объект, тот просто удаляется из карты.

Блок catch без указания переменной (RFC)


                try {
                    // Something goes wrong
                } catch (Exception) {
                    Log::error("Something went wrong");
                }
            

Разрешена запятая в конце списка параметров (RFC) и в списке use замыканий (RFC)


                public function(
                    string $a,
                    int $b,
                    Foo $foo,
                ) {
                    // …
                }
            

Достойно упоминания:

  • Оператор @ больше не подавляет фатальные ошибки.
  • Новый тип mixed RFC
  • Добавление ::class для объектов
  • str_contains(), str_starts_with(), str_ends_with()
  • Фатальная ошибка при несовместимости сигнатур методов RFC
  • Правильные сигнатуры магических методов RFC

https://vasishakd.github.io/php8