Вийшов PHP 8.5.0. Розбираємо, що в ній нового та цікавого

З виходу РНР 8.4.0 пройшов вже рік, і ось настав час для релізу нової версії — 8.5.0. Давайте подивимося, що в ній цікавого та важливого.

Головні зміни

Розширення URI

У PHP 8.5 з’явилося вбудоване розширення для роботи з URI та URL, яке базується на uriparser (RFC 3986) і Lexbor (WHATWG URL). Воно дає змогу отримувати надійний, стандартизований спосіб розбору та нормалізації адрес без необхідності вручну обробляти рядки чи покладатися на parse_url(), яке роками було джерелом неоднозначностей.

Тепер можна створювати об’єкт Uri й отримувати, наприклад, хост через метод getHost(), а не вручну витягувати його з масиву.

PHP 8.4 і раніше:

$components = parse_url('https://php.net/releases/8.4/en.php');
var_dump($components['host']);
// string(7) "php.net"

PHP 8.5:

use Uri\Rfc3986\Uri;
$uri = new Uri('https://php.net/releases/8.5/en.php');
var_dump($uri->getHost());
// string(7) "php.net"

Оператор Pipe (|>)

Новий оператор |> вводить у PHP можливість лінійно будувати трансформації значень, фактично, створювати читабельні конвеєри обробки. Замість вкладених викликів, де доводиться читати код зсередини назовні, тепер можна описати ланцюжок дій у тому порядку, у якому вони відбуваються.

Після передання в pipe результат кожного виразу переходить у наступний, тому такі фрагменти, як побудова slug, стають послідовними і простими для модифікації.

PHP 8.4 і раніше:

$title = ' PHP 8.5 Released ';
$slug = strtolower(
    str_replace('.', '',
        str_replace(' ', '-',
            trim($title)
        )
    )
);
var_dump($slug);
// string(15) "php-85-released"

PHP 8.5:

$title = ' PHP 8.5 Released ';
$slug = $title
    |> trim(...)
    |> (fn($str) => str_replace(' ', '-', $str))
    |> (fn($str) => str_replace('.', '', $str))
    |> strtolower(...);
var_dump($slug);
// string(15) "php-85-released"

Clone With

PHP 8.5 робить роботу з immutable та readonly об’єктами значно зручнішою. Тепер під час клонування можна одразу передати перелік властивостей, які слід змінити, просто через другий аргумент виклику clone().

Патерн «with-er» стає дуже компактним. Розробник може створити копію об’єкта з однією зміненою властивістю одним рядком.

PHP 8.4 і раніше:

readonly class Color
{
    public function __construct(
        public int $red,
        public int $green,
        public int $blue,
        public int $alpha = 255,
    ) {}
    public function withAlpha(int $alpha): self
    {
        $values = get_object_vars($this);
        $values['alpha'] = $alpha;
        return new self(...$values);
    }
}
$blue = new Color(79, 91, 147);
$transparentBlue = $blue->withAlpha(128);

PHP 8.5:

readonly class Color
{
    public function __construct(
        public int $red,
        public int $green,
        public int $blue,
        public int $alpha = 255,
    ) {}
    public function withAlpha(int $alpha): self
    {
        return clone($this, [
            'alpha' => $alpha,
        ]);
    }
}
$blue = new Color(79, 91, 147);
$transparentBlue = $blue->withAlpha(128);

Атрибут #[\NoDiscard]

У новій версії можна позначити функцію атрибутом #[\NoDiscard], що змусить PHP попереджати, якщо повернуте значення не використали. Це покращує безпеку API й допомагає уникати ситуацій, коли важливий результат виклику десь загубився у процесі. Якщо розробник свідомо ігнорує результат, потрібно явно привести його до (void).

PHP 8.4 і раніше:

function getPhpVersion(): string
{
    return 'PHP 8.4';
}
getPhpVersion(); // No warning

PHP 8.5:

#[\NoDiscard]
function getPhpVersion(): string
{
    return 'PHP 8.5';
}
getPhpVersion();
// Warning: The return value of function getPhpVersion() should
// either be used or intentionally ignored by casting it as (void)

Замикання і first-class callables у константних виразах

PHP тепер дозволяє використовувати статичні замикання та first-class callables у контекстах, які раніше були недоступними, наприклад, у константних виразах, що застосовуються в атрибутах.

Це відкриває можливість безпосередньо в атрибуті описати невеликий фрагмент бізнес-логіки, як-от правило доступу чи локальний валідатор, без зайвих обгорток, зовнішніх класів або глобальних функцій.

PHP 8.4 і раніше:

final class PostsController
{
    #[AccessControl(
        new Expression('request.user === post.getAuthor()'),
    )]
    public function update(
        Request $request,
        Post $post,
    ): Response {
        // ...
    }
}

PHP 8.5:

final class PostsController
{
    #[AccessControl(static function (
        Request $request,
        Post $post,
    ): bool {
        return $request->user === $post->getAuthor();
    })]
    public function update(
        Request $request,
        Post $post,
    ): Response {
        // ...
    }
}

Persistent cURL Share Handles

У PHP 8.5 з’явилася можливість створювати persistent share handles через curl_share_init_persistent().

Поговорімо про це на DOU PHP Meetup 😉

На відміну від звичайних share handles, такі об’єкти не знищуються наприкінці запиту й можуть бути повторно використані в наступних запитах, якщо мають ті самі опції. В результаті маємо, що DNS, TCP або TLS з’єднання можуть кешуватися довше.

PHP 8.4 і раніше:

$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
$ch = curl_init('https://php.net/');
curl_setopt($ch, CURLOPT_SHARE, $sh);
curl_exec($ch);

PHP 8.5:

$sh = curl_share_init_persistent([
    CURL_LOCK_DATA_DNS,
    CURL_LOCK_DATA_CONNECT,
]);
$ch = curl_init('https://php.net/');
curl_setopt($ch, CURLOPT_SHARE, $sh);
// This may now reuse the connection from an earlier SAPI request
curl_exec($ch);

array_first() і array_last()

У мові з’явилися дрібні, але дуже зручні функції array_first() і array_last(), які повертають відповідно перший та останній елементи масиву або null, якщо масив порожній.

$lastEvent = array_last($events);

Інші зміни

  • Додано покращене звуження типів, що дозволяє компілятору точніше визначати недосяжні умовні гілки.
  • Посилено контроль undefined і null, що допомагає уникати прихованих ситуацій із відсутніми значеннями.
  • Покращено взаємодію з модулями, що усуває дрібні конфлікти під час імпорту у великих проєктах.
  • Оптимізовано розпізнавання ключів об’єктів, що зменшує ризик звернення до неіснуючих властивостей.
  • Уніфіковано роботу з функціональними типами, що знижує потребу у зайвих уточненнях.
  • Оновлено повідомлення про помилки, що робить діагностику типів значно зрозумілішою.

Завантажити РНР 8.5.0 можна на офіційному сайті.

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось13
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

поступово різні функції з одних мов переходять у php. Як говорять, з часом php буде важко відрізнити від java

Підписатись на коментарі