Вийшов 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 можна на офіційному сайті.
2 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів