<? phpukraine ЕКОСИСТЕМА
⌕Пошук по платформі
PHP · ЩО НОВОГО

Що нового в PHP 7.4

  1. 01Typed properties: тип у кожної властивості класу, PHP перевіряє його при кожному присвоєнні.
  2. 02Arrow functions fn, оператор ??=, spread у масивах, коваріантні типи та preloading в OPcache.
  3. 03Підтримку завершено 28 листопада 2022: патчів безпеки більше не буде, час переходити на 8.x.
СТАТУС Не підтримується
Реліз
28 листопада 2019
Останній патч
7.4.33
Активна підтримка до
28.11.2021
Безпека до
28.11.2022
НОВІ МОЖЛИВОСТІ · 7

Нові можливості

1.1 · RFC

Typed properties

Властивості класу отримали типи, як уже мали параметри й результати функцій. PHP перевіряє значення при кожному присвоєнні, а не лише в сетері, і не дає прочитати властивість до ініціалізації. Анотація @var для цього більше не потрібна.

+ PHP 7.4
public int $salary;
− PHP 7.3
/** @var int */
private $salary;

public function setSalary($salary)
{
    $this->salary = (int) $salary;
}
1.2 · RFC

Arrow functions

fn ($x) => $x * $rate повертає результат одного виразу і сам захоплює змінні батьківської області за значенням. Список use більше не потрібен, тож колбеки для array_map() чи usort() вміщаються в один рядок.

+ PHP 7.4
$taxed = array_map(fn ($price) => $price * $rate, $prices);
− PHP 7.3
$taxed = array_map(function ($price) use ($rate) {
    return $price * $rate;
}, $prices);
1.3 · RFC

Коваріантність типів

Метод у дочірньому класі тепер може звузити тип результату, скажімо з Animal до Cat, і розширити тип параметра. До 7.4 типи мали збігатися з батьківськими, тож фабрики повертали базовий тип, а справжній дописували в PHPDoc.

+ PHP 7.4
class CatShelter extends Shelter
{
    public function adopt(): Cat { /* … */ }
}
− PHP 7.3
class CatShelter extends Shelter
{
    /** @return Cat */
    public function adopt(): Animal { /* … */ }
}
1.4 · RFC

WeakReference

WeakReference::create() тримає посилання, але не продовжує обʼєкту життя. Коли інших посилань не лишилось, get() повертає null. Це основа для кешів і реєстрів, які не мають тримати обʼєкти в памʼяті вічно.

+ PHP 7.4
$cache[$id] = WeakReference::create($user);
$cached = $cache[$id]->get(); // null, якщо обʼєкт уже знищено
− PHP 7.3
$cache[$id] = $user;
// обʼєкт живе, поки живе кеш
1.5 · RFC

__serialize() і __unserialize()

Обʼєкт сам вирішує, що потрапить у serialize(): __serialize() повертає масив, а __unserialize() отримує його назад. Вони замінюють і пару __sleep()/__wakeup(), і інтерфейс Serializable, де доводилось серіалізувати рядок усередині рядка.

+ PHP 7.4
public function __serialize(): array
{
    return ['user' => $this->user];
}

public function __unserialize(array $data): void
{
    $this->user = $data['user'];
}
− PHP 7.3
class Session implements Serializable
{
    public function serialize() { return serialize([$this->user]); }
    public function unserialize($data) { [$this->user] = unserialize($data); }
}
1.6 · RFC

Винятки з __toString()

До 7.4 виняток з __toString() закінчувався фатальною помилкою, яку не перехопиш. Тепер він летить звичайним шляхом, і try/catch навколо echo чи конкатенації його ловить. Обгортати тіло методу в catch з поверненням порожнього рядка більше не треба.

+ PHP 7.4
public function __toString(): string
{
    return $this->format();
}
− PHP 7.3
public function __toString(): string
{
    try {
        return $this->format();
    } catch (Throwable $e) {
        return '';
    }
}
1.7 · RFC

FFI

Розширення FFI завантажує спільну бібліотеку і дає викликати її функції та працювати з C-структурами з PHP-коду. Раніше для цього писали розширення на C. За замовчуванням ffi.enable=preload, тож у вебзапитах FFI доступне лише з файлів, підключених через preloading.

+ PHP 7.4
$libc = FFI::cdef('int abs(int);', 'libc.so.6');
echo $libc->abs(-42); // 42
− PHP 7.3
// окреме розширення на C, зібране під кожну версію PHP
СИНТАКСИС · 3

Синтаксис

2.1 · RFC

Оператор ??=

$a ??= $b присвоює $b, тільки коли $a не існує або дорівнює null. Найчастіше так задають значення за замовчуванням для ключів масиву, де раніше ліву частину писали двічі.

+ PHP 7.4
$options['timeout'] ??= 30;
− PHP 7.3
$options['timeout'] = $options['timeout'] ?? 30;
2.2 · RFC

Spread у масивах

Оператор ... тепер розпаковує масиви й Traversable всередині масиву, зокрема генератори. У 7.4 і 8.0 це працює лише з числовими ключами, рядкові дозволили у 8.1. Заразом array_merge() тепер можна викликати без аргументів, тож array_merge(...$lists) не ламається на порожньому списку.

+ PHP 7.4
$stack = [...$backend, 'Docker', ...$frontend];
− PHP 7.3
$stack = array_merge($backend, ['Docker'], $frontend);
2.3 · RFC

Роздільник у числах

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

+ PHP 7.4
$budget = 1_500_000;
− PHP 7.3
$budget = 1500000;
ФУНКЦІЇ · 2

Нові функції

3.1 · RFC

mb_str_split()

str_split() ріже рядок по байтах, тому кирилиця розпадається на половинки символів. mb_str_split() ділить за символами в потрібному кодуванні і приймає довжину шматка.

+ PHP 7.4
$letters = mb_str_split($word);
− PHP 7.3
$letters = preg_split('//u', $word, -1, PREG_SPLIT_NO_EMPTY);
3.2 · НОВЕ

strip_tags() з масивом тегів

Другий аргумент strip_tags() приймає масив імен тегів, який зручно тримати в конфігурації. Від XSS функція як і раніше не захищає: атрибути дозволених тегів лишаються, а вміст script стає звичайним текстом.

+ PHP 7.4
strip_tags($html, ['b', 'a']);
− PHP 7.3
strip_tags($html, '<b><a>');
ПРОДУКТИВНІСТЬ · 1

Продуктивність

4.1 · ДВИГУН

Preloading

Скрипт з opcache.preload виконується під час старту PHP-FPM, і всі класи, які він підключив, доступні кожному запиту зі спільної памʼяті без автозавантаження. Ціна в тому, що після зміни цих файлів сервер треба перезапустити.

+ PHP 7.4
opcache.enable=1
opcache.preload=/var/www/app/preload.php
opcache.preload_user=www-data
− PHP 7.3
opcache.enable=1
; класи підтягуються автозавантажувачем у кожному запиті
БЕЗПЕКА · 1

Безпека

5.1 · RFC

Реєстр алгоритмів паролів

Алгоритми хешування паролів отримали рядкові ідентифікатори на кшталт '2y' чи 'argon2id', а password_algos() повертає ті, що є в цій збірці. Якщо PHP зібрано без libargon2, але з sodium, Argon2 для password_hash() береться із sodium.

+ PHP 7.4
if (in_array('argon2id', password_algos(), true)) {
    $hash = password_hash($password, PASSWORD_ARGON2ID);
}
− PHP 7.3
if (defined('PASSWORD_ARGON2ID')) {
    $hash = password_hash($password, PASSWORD_ARGON2ID);
}
DEPRECATED

Застаріло

Ще працює, але дає попередження і зникне в одній із наступних версій.

$a ? $b : $c ? $d : $eВкладений тернарний оператор без дужок. Розставте їх явно, у 8.0 це вже помилка компіляції.
$str{0}Фігурні дужки для доступу за індексом. Пишіть $str[0], у 8.0 цей синтаксис прибрали.
(real) і is_real()Старі синоніми float. Використовуйте (float) і is_float().
array_key_exists() з обʼєктомДля властивостей обʼєкта є property_exists() або isset().
implode($parts, ', ')Старий порядок аргументів. Роздільник іде першим, implode(', ', $parts).
"Сума: " . $a + $bКрапка разом з + чи - без дужок. У 8.0 + і - виконуються раніше, і результат зміниться.
money_format() і get_magic_quotes_gpc()Разом з hebrevc() і convert_cyr_string() видалені у 8.0. Гроші форматує NumberFormatter з intl.
BREAKING

Ламає сумісність

Перевірте це до оновлення: такий код перестане працювати або поводитиметься інакше.

Індекс у null, bool чи int$value['key'] на скалярі чи null тепер дає Notice. Часто так читають результат функції, що повернула false.
fn стало ключовим словомФункції й класи з назвою fn перестануть компілюватися. Методи й константи класу з такою назвою можна лишити.
PASSWORD_* стали рядкамиPASSWORD_DEFAULT і PASSWORD_BCRYPT тепер '2y', а не 1. Порівняння з числом у коді перестане спрацьовувати.
ext/wddx, ext/interbase, ext/recodeВинесено з ядра в PECL. До Firebird лишається доступ через драйвер PDO.

Як оновитися

0 / 6