PHP 8.3!

PHP 8.3: Что нового и почему это важно?

PHP 8.3 уже здесь, и он предлагает немало интересных улучшений и новых возможностей, которые сделают вашу жизнь как PHP-разработчика проще и продуктивнее. Этот релиз не является революционным, но он содержит достаточно значимых изменений, чтобы его стоит изучить и начать применять. Мы поговорим о ключевых изменениях, касающихся производительности, удобства разработки и безопасности. Подготовка к переходу на PHP 8.3 и понимание преимуществ, которые он предоставляет, крайне важны для поддержания конкурентоспособности ваших проектов.

В этом посте мы рассмотрим наиболее значимые новые функции и улучшения в PHP 8.3, от новых возможностей для работы с классами и свойствами до улучшений в работе с массивами и типами. Мы также предоставим практические примеры кода, чтобы помочь вам понять, как использовать эти новые возможности в своих проектах. Уделите внимание деталям – некоторые изменения, хоть и незначительные на первый взгляд, могут существенно повлиять на ваш код.

Так что пристегните ремни, и давайте погрузимся в мир PHP 8.3!

1. Радикальные Типы для Свойств Классов (Radix Types)

До PHP 8.3, при работе с радикальными типами (например, `int`, `string`, `bool`) в свойствах классов, PHP, по сути, игнорировал их. Свойства все равно могли хранить значения любого типа. Это создавало ситуации, когда контроль типов работал не так, как ожидалось. В PHP 8.3 это исправлено. Теперь, если вы объявляете свойство с радикальным типом, PHP будет активно проверять, соответствует ли присваиваемое значение этому типу. Это позволяет выявлять потенциальные ошибки на ранних этапах разработки и улучшает общую надежность кода.


class User {
  public int $age;
  public string $name;

  public function __construct(int $age, string $name) {
    $this->age = $age;
    $this->name = $name;
  }

  public function getAge(): int {
    return $this->age;
  }
}

try {
  $user = new User(30, "Alice");
  $user->age = "twenty"; // This will now throw a TypeError
} catch (TypeError $e) {
  echo "Error: " . $e->getMessage() . "\n";
}

echo $user->getAge() . "\n";
  

Заметьте, что попытка присвоить свойству $age строку вызовет TypeError. Это значительно повышает безопасность и предсказуемость кода.

2. `static` return type для методов класса

PHP 8.3 вводит возможность использования ключевого слова `static` в качестве типа возвращаемого значения для методов класса. Это означает, что метод должен возвращать объект того же класса, что и сам метод, или производный от него. Это позволяет повысить строгость типизации и упростить код, особенно при работе с наследованием и полиморфизмом. Благодаря этому, рефакторинг и поддержка больших кодовых баз становятся значительно проще и безопаснее.


class Animal {
  public static function create(): static {
    return new Animal();
  }
}

class Dog extends Animal {
    public static function create(): static {
        return new Dog();
    }
}

$animal = Animal::create();
$dog = Dog::create();

if ($animal instanceof Animal) {
    echo "Animal is an Animal\n";
}

if ($dog instanceof Dog) {
    echo "Dog is a Dog\n";
}

if ($animal instanceof Dog) {
   echo "Animal is a Dog (This won't happen)\n"; //Will not execute
}
  

В данном примере, `Animal::create()` и `Dog::create()` оба возвращают объекты соответствующих классов. Это позволяет писать более гибкий и надежный код.

3. Улучшения в работе с `array_unique` и `array_column`

PHP 8.3 вносит улучшения в встроенные функции `array_unique` и `array_column`, которые часто используются при работе с массивами. В `array_unique`, теперь можно указать callback функцию для сравнения элементов, что дает гораздо больше гибкости при удалении дубликатов, особенно для сложных объектов.


class Point {
  public int $x;
  public int $y;

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

$points = [
  new Point(1, 1),
  new Point(2, 2),
  new Point(1, 1),
  new Point(3, 3),
];

$uniquePoints = array_unique($points, function (Point $p1, Point $p2) {
  return $p1->x === $p2->x && $p1->y === $p2->y;
});

print_r($uniquePoints);
  

Без callback функции, `array_unique` удалял бы объекты Point как дубликаты только если они были идентичными экземплярами (то есть одним и тем же объектом в памяти). С callback функцией, мы можем сравнить их по координатам.

У `array_column` улучшена обработка ошибок. Теперь, если указан некорректный ключ, функция не будет прерывать выполнение скрипта, а вернет `null`.

4. Оптимизация работы с `?` (Nullsafe Operator)

Оператор Nullsafe (`?`) — это удобный способ избежать ошибок при работе с потенциально `null` объектами. В PHP 8.3 произведена внутренняя оптимизация этого оператора, что приводит к незначительному, но заметному приросту производительности, особенно в часто используемых кодовых ветвях. Это особенно важно для высоконагруженных приложений.


class User {
  public ?Address $address;

  public function __construct(?Address $address) {
    $this->address = $address;
  }
}

class Address {
  public string $city;

  public function __construct(string $city) {
    $this->city = $city;
  }
}


$user = new User(new Address("New York"));

$city = $user?->address?->city;

echo $city . "\n";

$user2 = new User(null);

$city2 = $user2?->address?->city;

var_dump($city2); // Output: NULL

  

Благодаря оптимизации, цепочки Nullsafe операторов выполняются более эффективно, что улучшает общую производительность приложения.

Заключение

PHP 8.3 предлагает ряд интересных улучшений и новых возможностей, которые повышают производительность, безопасность и удобство разработки. Радикальные типы для свойств классов, `static` return type для методов, улучшения в работе с массивами и оптимизация `Nullsafe` оператора – все это делает PHP 8.3 более привлекательным для разработчиков. Рекомендуется начать переход на PHP 8.3 как можно скорее, чтобы воспользоваться всеми преимуществами этого нового релиза и поддерживать свои проекты современными и безопасными. Не забывайте тщательно тестировать свой код после обновления, чтобы убедиться в его корректной работе.