PHP 8.4: що нового і чи варто оновлюватися зараз

21 листопада 2024 року вийшла нова версія PHP 8.4, і це не просто чергове оновлення з виправленням помилок. Цей реліз приносить революційні зміни в синтаксис мови, які змусять переглянути підходи до написання коду. Property hooks, асиметрична видимість, HTML5-підтримка в DOM — все це вже доступно.

У цій статті розповім про найважливіші PHP 8.4 features, покажу реальні приклади використання і, що найголовніше, допоможу вам вирішити — чи варто оновлюватися саме зараз.

Коли вийшов PHP 8.4 і що варто знати про підтримку

PHP 8.4 офіційно випустили 21 листопада 2024 року. Це перша версія, яка вийшла за новим графіком підтримки, схваленим спільнотою раніше цього року. Тепер цикл розробки стартує на місяць пізніше, а фаза релізних кандидатів скоротилася з шести до чотирьох версій.

Що стосується підтримки, то PHP 8.4 отримає два роки активних оновлень (виправлення багів і безпека) плюс два роки лише критичних патчів безпеки. Загалом це чотири роки підтримки до 31 грудня 2028 року. Важливий момент: тепер всі версії PHP досягають End of Life саме 31 грудня, а не в річницю релізу, як було раніше.

Графік підтримки PHP 8.x версій
Графік підтримки PHP 8.4

Property Hooks — революція в PHP 8.4

Найбільша фіча PHP 8.4 — це property hooks. Якщо ви коли-небудь писали getter’и і setter’и в PHP, то знаєте, скільки boilerplate-коду це генерує. Зараз все змінюється кардинально.

Раніше, щоб контролювати доступ до властивості, доводилося робити так:

<?php
class User {
    private string $email;
    
    public function getEmail(): string {
        return $this->email;
    }
    
    public function setEmail(string $email): void {
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException('Invalid email');
        }
        $this->email = $email;
    }
}
?>Code language: HTML, XML (xml)

Тепер у PHP 8.4 це виглядає набагато елегантніше:

<?php
class User {
    public string $email {
        set {
            if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
                throw new InvalidArgumentException('Invalid email');
            }
            $this->email = $value;
        }
    }
}

$user = new User();
$user->email = 'test@example.com'; // Автоматично викличеться hook
?>Code language: HTML, XML (xml)

Hooks працюють як для читання (get), так і для запису (set). Можна визначити лише один з них або обидва. Особливо круто це працює з віртуальними властивостями, які обчислюються на льоту:

<?php
class Product {
    public function __construct(
        public float $price,
        public float $tax = 0.20
    ) {}
    
    public float $priceWithTax {
        get => $this->price * (1 + $this->tax);
    }
}

$product = new Product(100);
echo $product->priceWithTax; // 120.0
?>Code language: HTML, XML (xml)

Це дозволяє позбутися сотень рядків коду в типових проєктах. Детальніше про property hooks можна прочитати в офіційній документації PHP.

Асиметрична видимість у PHP 8.4

Друга найочікуваніша фіча — asymmetric visibility. Вона вирішує проблему, з якою стикається кожен PHP-розробник: як зробити властивість публічно доступною для читання, але змінюваною лише всередині класу.

Раніше доводилося використовувати private властивість з public getter’ом або readonly (що не давало змінювати значення навіть всередині класу після ініціалізації). Тепер можна зробити так:

<?php
class Counter {
    public private(set) int $count = 0;
    
    public function increment(): void {
        $this->count++; // Можна змінювати всередині класу
    }
}

$counter = new Counter();
echo $counter->count; // 0 - читання працює
$counter->increment();
echo $counter->count; // 1

$counter->count = 10; // Fatal error - неможливо змінити ззовні
?>Code language: HTML, XML (xml)

Синтаксис public private(set) означає: публічне читання, приватний запис. Можна комбінувати по-різному: public protected(set), protected private(set) тощо. Це значно спрощує інкапсуляцію даних.

Нові можливості роботи з масивами в PHP 8.4

PHP 8.4 додає чотири нові функції для роботи з масивами, які давно просили розробники. Ці функції роблять код чистішим і зрозумілішим.

array_find() та array_find_key()

Функція array_find() шукає перший елемент масиву, що відповідає умові. Це схоже на array_filter(), але повертає лише перший результат:

<?php
$users = [
    ['id' => 1, 'name' => 'Олег', 'age' => 25],
    ['id' => 2, 'name' => 'Марія', 'age' => 30],
    ['id' => 3, 'name' => 'Андрій', 'age' => 28],
];

// Знайти першого користувача старше 27 років
$user = array_find($users, fn($u) => $u['age'] > 27);
print_r($user); 
// ['id' => 2, 'name' => 'Марія', 'age' => 30]

// Отримати ключ замість значення
$key = array_find_key($users, fn($u) => $u['age'] > 27);
echo $key; // 1
?>Code language: HTML, XML (xml)

array_any() та array_all()

Ці функції перевіряють, чи відповідають елементи масиву певній умові. array_any() повертає true, якщо хоча б один елемент відповідає умові, а array_all() — якщо всі елементи:

<?php
$numbers = [1, 2, 3, 4, 5];

// Чи є хоча б одне парне число?
$hasEven = array_any($numbers, fn($n) => $n % 2 === 0);
var_dump($hasEven); // true

// Чи всі числа додатні?
$allPositive = array_all($numbers, fn($n) => $n > 0);
var_dump($allPositive); // true

// Чи всі числа парні?
$allEven = array_all($numbers, fn($n) => $n % 2 === 0);
var_dump($allEven); // false
?>Code language: HTML, XML (xml)

Ці функції роблять код набагато читабельнішим порівняно з комбінацією array_filter() і empty().

HTML5-підтримка в DOM розширенні PHP 8.4

Нарешті! PHP підтримує HTML5. До PHP 8.4 DOM-розширення працювало лише з HTML 4.01, що створювало проблеми при парсингу сучасних веб-сторінок. Тепер додано новий клас Dom\HTMLDocument із повною підтримкою HTML5:

<?php
use Dom\HTMLDocument;

$html = '<!DOCTYPE html>
<html>
<body>
    <main>
        <article class="featured">PHP 8.4 підтримує HTML5!</article>
    </main>
</body>
</html>';

$doc = HTMLDocument::createFromString($html);

// CSS-селектори тепер працюють!
$article = $doc->querySelector('main > article.featured');
echo $article->textContent; // "PHP 8.4 підтримує HTML5!"

// Робота з класами елементів
var_dump($article->classList->contains('featured')); // true
?>Code language: HTML, XML (xml)

Новий API включає підтримку CSS-селекторів через querySelector(), роботу з classList, а також правильний парсинг HTML5-тегів на кшталт <article>, <section>, <nav>. Старий DOMDocument залишається для зворотної сумісності.

PHP Property Hooks - До і Після
Старий vs новий DOM API

Виклик методів без дужок у PHP 8.4

Одна з тих “маленьких” фіч, яка насправді економить купу нервів. Тепер можна викликати методи на щойно створених об’єктах без зайвих дужок:

<?php
// Раніше доводилося робити так
$name = (new ReflectionClass($object))->getShortName();

// Тепер можна без дужок
$name = new ReflectionClass($object)->getShortName();

// Працює не тільки з методами
$value = new MyClass()->property;
$constant = new MyClass()::CONSTANT;
$result = new Calculator()::staticMethod();
?>Code language: HTML, XML (xml)

Це може здаватися дрібницею, але коли пишеш такий код щодня, економія дужок справді відчутна. Код стає чистішим і природнішим.

Інші корисні зміни в PHP 8.4

Крім великих фіч, PHP 8.4 приносить безліч менших, але не менш корисних покращень.

Атрибут #[Deprecated]: Тепер можна позначати застарілий код офіційним атрибутом PHP замість phpDoc коментарів:

<?php
#[Deprecated("використовуйте newMethod()", since: "1.5.0")]
function oldMethod() {
    // Застарілий код
}
?>Code language: HTML, XML (xml)

Multibyte trim функції: Додано mb_trim(), mb_ltrim(), mb_rtrim() для правильної роботи з багатобайтовими рядками:

<?php
$text = " Привіт "; // Японські пробіли
$cleaned = mb_trim($text);
echo $cleaned; // "Привіт"
?>Code language: HTML, XML (xml)

BCMath об’єктний API: Тепер можна працювати з великими числами через об’єкти з підтримкою операторів:

<?php
use BCMath\Number;

$num1 = new Number('123456789012345678901234567890');
$num2 = new Number('987654321098765432109876543210');
$result = $num1 + $num2;
echo $result->value; // Результат додавання
?>Code language: HTML, XML (xml)

Детальніше про всі зміни можна прочитати в офіційному анонсі PHP 8.4.

Що застаріло в PHP 8.4

З кожною новою версією PHP позбавляється застарілих механізмів. У PHP 8.4 кілька важливих deprecations, про які треба знати.

Implicit nullable типи тепер застаріли. Раніше можна було писати:

<?php
// Застаріло
function test(string $param = null) {}

// Правильно
function test(?string $param = null) {}
?>Code language: HTML, XML (xml)

GET/POST сесії через URL більше не підтримуються. Це було небезпечно з точки зору безпеки, тому PHP нарешті від цього відмовляється. Тепер сесії працюють виключно через cookies.

Константа E_STRICT повністю видалена, оскільки всі її перевірки тепер інтегровані в інші рівні помилок.

Повний список застарілих можливостей доступний у гайді міграції PHP 8.4.

Переваги оновлення до PHP 8.4

  • Менше boilerplate-коду: Property hooks і asymmetric visibility радикально скорочують обсяг типового коду
  • Кращий DX (Developer Experience): Виклики методів без дужок, нові array-функції роблять код природнішим
  • Сучасна робота з HTML: HTML5-підтримка в DOM нарешті дозволяє парсити сучасні веб-сторінки
  • Продуктивність: Хоча це не основний фокус релізу, внутрішні оптимізації дають приріст швидкості
  • Безпека: Збільшений bcrypt cost до 12, відмова від небезпечних механізмів сесій

Недоліки та ризики оновлення PHP 8.4

  • Breaking changes: Деякі застарілі можливості вже видалені, що може зламати старий код
  • Сумісність бібліотек: Не всі популярні пакети встигли оновитися під PHP 8.4
  • Хостинг: Не всі провайдери ще підтримують PHP 8.4 у продакшені
  • Час на тестування: Потрібен час для перевірки всієї кодової бази на сумісність
  • Навчання команди: Нові features потребують часу на вивчення та адаптацію

Чи варто оновлюватися до PHP 8.4 зараз

Відповідь залежить від вашої ситуації. Якщо ви працюєте над новим проєктом або маєте добре покриту тестами кодову базу — однозначно варто. Property hooks і asymmetric visibility самі по собі виправдовують оновлення завдяки скороченню коду.

Для legacy-проєктів рекомендую почекати кілька місяців. Дайте екосистемі час адаптуватися, популярним бібліотекам — оновитися, а хостинг-провайдерам — стабілізувати підтримку. PHP 8.4 отримає підтримку до кінця 2028 року, тому поспішати немає сенсу.

Перед оновленням обов’язково протестуйте код на staging-середовищі. Використовуйте інструменти статичного аналізу типу PHPStan або Psalm, щоб виявити потенційні проблеми. Якщо працюєте з Laravel, почекайте офіційного підтвердження сумісності від Taylor Otwell.

Більше про правильне налаштування PHP-середовища можна прочитати в нашій статті про налаштування Laravel на macOS.

Рекомендуємо прочитати

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *