PHP 8.2: Головні нововведення
Огляд для оновлення з PHP 8.1.x до 8.2.x: нові можливості мови, захист чутливих параметрів у трасуванні, суворіші правила для рядків і каталогів, плюс deprecations, які краще закрити до наступного релізу.
Зміст (Оглавлення)
- #[SensitiveParameter] і трасування
- Readonly-класи
- Окремі типи (
null,false,true) та DNF - Константи в трейтах і enum у константних виразах
- INI:
error_log_mode - Розширення Random
- Розширення: cURL, PCRE
- Зворотно несумісні зміни (міграція)
- Deprecations (виправити до появи помилок)
- Розширення та runtime
PHP 8.2 посилює вимогу до явності: readonly-класи, виразніші типи (зокрема DNF), атрибут #[SensitiveParameter] проти витоку секретів у backtrace. Також змінюється поведінка низки функцій (ASCII-регістр без locale, str_split(''), glob() за open_basedir) і оголошуються застарілими динамічні властивості без явного дозволу.
#[SensitiveParameter] і трасування
#[\SensitiveParameter] приховує значення параметра у stack traces — менше випадкових паролів у логах.
function connect(#[\SensitiveParameter] string $password): void
{
throw new RuntimeException('fail');
}
Не покладайтеся лише на атрибут: у проді не виводьте сирі винятки клієнту, а логи будуйте з дисципліною щодо секретів.
Практичний рецепт: позначайте секрети на межі
Ставте #[\SensitiveParameter] на параметри, які можуть потрапити в exceptions (обгортки клієнтів, auth helper’и). Stack trace лишається корисним, але секрети не «витікають» у логи.
final class ApiClient
{
public function __construct(
private readonly string $baseUrl,
#[\SensitiveParameter] private readonly string $token,
) {}
}
Readonly-класи
readonly class робить усі властивості екземпляра readonly і ініціалізує їх у конструкторі.
readonly class Point
{
public function __construct(
public int $x,
public int $y,
) {}
}
Зручно для immutable value object і DTO: після конструктора граф об’єкта не змінюється «ззовні» без явних копій.
Окремі типи (null, false, true) та DNF
null, false, true можна використовувати як окремі типи в оголошеннях (не лише як частина union у старих формах).
DNF (диюнктивна нормальна форма) поєднує union і intersection у нормалізованому вигляді — наприклад (A&B)|null, щоб описати API без втрати nullability.
function accepts((Countable&Traversable)|null $c): void {}
Константи в трейтах і enum у константних виразах
- Константи в трейтах.
- Звернення до enum у дозволених константних контекстах.
INI: error_log_mode
error_log_mode задає права файлу error log під час створення PHP.
Розширення Random
Розширення Random зводить до ладу API генерації випадкових чисел: зрозуміліші рушії, менше випадкового змішування старих функцій. Для нового коду з відтворюваними seed або криптостійкими токенами орієнтуйтеся на класи Random\Engine і Random\Randomizer з мануала.
Практичний рецепт: Randomizer для токенів і вибірки
$engine = new Random\Engine\Mt19937(random_int());
$randomizer = new Random\Randomizer($engine);
$token = $randomizer->getBytesFromString('0123456789abcdef', 32);
У тестах використовуйте seeded engine для відтворюваності; для секретів оберіть криптографічно доречний Random\Engine за документацією.
Розширення: cURL, PCRE
- cURL:
CURLINFO_EFFECTIVE_METHOD,curl_upkeep(), нові константи залежно від libcurl. - PCRE: модифікатор
n— звичайні групи не захоплюють, лише іменовані.
Зворотно несумісні зміни (міграція)
Дата й час
- Tentative
staticу factory-методівDateTime/DateTimeImmutable. - Суворіші відносні формати для
number.
Стандартна бібліотека
- Базові функції регістру — лише ASCII, не locale; локалізований регістр — mbstring.
str_split('')повертає порожній масив.glob/GlobIteratorіopen_basedir— зміни[]/falseі попереджень.FilesystemIterator:SKIP_DOTSбільше не «вшитий» у стару поведінку за замовчуванням — задайте прапорці явно.ksort/krsort: приSORT_REGULARзастосовуються правила PHP 8 для числових рядків послідовно з іншими порівняннями.var_exportекспортує повністю кваліфіковані імена класів (початковий зворотний слеш не опускається).
ODBC / PDO_ODBC
Екранування імені користувача та пароля при дописуванні до рядка підключення.
Примітка: date_default_timezone_get() у деяких випадках може повертати UTC, якщо зону не задано явно — перевірте припущення про часовий пояс після оновлення.
SPL
Деякі методи SplFileObject суворіше дотримуються сигнатур; для частини методів звузили типи повернення (hasChildren, getChildren тощо) — перегляньте власні нащадки.
Deprecations
Динамічні властивості
Створення динамічних властивостей на довільних класах застаріло, якщо клас не має #[\AllowDynamicProperties] (або не успадковує типи на кшталт stdClass, де це дозволено). Краще оголосити властивості, використати WeakMap для зовнішніх метаданих або явні __get/__set.
Часткові callables
Форми, які приймає лише call_user_func(), а не виклик $callable() — наприклад "self::method", "parent::method", певні масивні форми — застарілі. Нормалізуйте до Foo::bar або [Class::class, 'method'].
Інтерполяція рядків
Стиль "${var}" / "${expr}" застарілий; використовуйте "{$var}" або конкатенацію.
Інше
utf8_encode/utf8_decode: deprecated (кращеmb_convert_encodingабоiconv).
Розширення та runtime
- OpenSSL: підтримка AEAD chacha20-poly1305, де доступно в збірці.
- OCI8: налаштування prefetch для LOB через INI та
oci_set_prefetch_lob()на підтримуваних версіях Oracle. - DBA (LMDB): прапорці для поведінки з підкаталогами під час створення файлів БД.
Підсумок
PHP 8.2 вигідний командам, які явно описують модель даних: readonly-класи, точніші типи, менше випадкових витоків через #[\SensitiveParameter], а deprecation підштовхує до оголошених властивостей і сучасних callables. Окремо закладіть час на перевірки рядків і локалі (ASCII case у базових функціях), timezone, open_basedir + glob та інтеграційні тести ODBC/PDO_ODBC після змін екранування в DSN.