PHP 8.3: Головні нововведення
Реліз про «полірування» для команд на PHP 8.2.x: міцніші інваріанти (#[Override], типізовані константи), зручніший JSON і рядки (json_validate, str_increment/str_decrement), плюс довгий хвіст дрібних змін runtime, які проявляються під навантаженням або в рідких гілках коду.
Зміст
#[\Override]— відсутні override на етапі компіляції- Типізовані константи класу
- Readonly: анонімні класи й клонування
- Покращення мови (quality-of-life)
- Нові функції (
json_validate,str_*, DOM, Random тощо) - Зворотно несумісні зміни (міграційні нотатки)
- Deprecated (інкремент/декремент рядків,
get_class(), assert INI) - Інші зміни та експлуатація (gc_status, streams, highlights)
PHP 8.3 менше про одну «головну» фічу й більше про жорсткі контракти: можна задати типи констант, перевіряти override через #[\Override] і валідувати JSON без декодування — водночас рушій і стандартна бібліотека місцями суворіші (range(), proc_get_status(), винятки в Date/DOM). Закладіть час на QA навколо інкременту/декременту рядків (deprecated оператори, нові helper’и), reflection (ReflectionProperty::setValue) і налаштувань assert (deprecated INI та assert_options()).
#[\Override] — відсутні override на етапі компіляції
Позначайте методи, які мають перевизначати батька або інтерфейс. Якщо ім’я помилкове або метод прибрали з батька, PHP падає рано, замість того щоб тихо додати новий метод.
interface Logger
{
public function log(string $message): void;
}
final class FileLogger implements Logger
{
#[\Override]
public function log(string $message): void
{
// ...
}
}
Особливо корисно у великих кодових базах під час рефакторингу інтерфейсів.
Типізовані константи класу
Константи в класах, інтерфейсах, трейтах і enum можуть оголошувати типи — константи наближаються до решти системи типів.
interface Config
{
public const string APP_NAME = 'MyApp';
}
Менше помилок «не той тип константи», які раніше спливали лише в місцях використання.
Readonly: анонімні класи й клонування
- Анонімні класи можна оголосити
readonly. - Readonly-властивості можна переініціалізувати під час
clone, коли це дозволяє граф об’єктів — клони immutable-об’єктів стають менш болісними, ніж чисто на патернах 8.2.
Покращення мови (quality-of-life)
- Динамічний доступ до константи класу:
SomeClass::{$name}для імен констант під час виконання. - Ініціалізатори static-змінних можуть містити довільні вирази (не лише константи).
finalдля методів трейта під час імпорту методу з трейта.- Замикання з magic methods можуть приймати іменовані аргументи під час виклику.
php.ini: синтаксис fallback/default для чистішої конфігурації.
Нові функції (json_validate, str_*, DOM, Random тощо)
json_validate()
Перевірка JSON без декодування у значення PHP — зручно для API, черг і швидкої перевірки перед дорогим json_decode().
if (!json_validate($payload)) {
throw new InvalidArgumentException('Invalid JSON');
}
$data = json_decode($payload, true, flags: JSON_THROW_ON_ERROR);
str_increment() / str_decrement()
Бажана заміна застарілим ++/-- для рядків (див. deprecations). Використовуйте для літерно-цифрових лічильників, де раніше покладалися на оператори інкременту.
$next = str_increment('a9'); // крок без рядкового ++
$prev = str_decrement($next);
DOM, Intl, Random, POSIX тощо
У PHP 8.3 додано багато методів DOM (наприклад insertAdjacentElement, getRootNode, replaceChildren), допоміжників Intl для календарів, методів Random у Randomizer (getFloat, nextFloat, …) і функцій POSIX (sysconf/pathconf/eaccess) — корисно для системних скриптів і tooling’у.
Зворотно несумісні зміни (міграційні нотатки)
Стек / таймери / fibers
- Глибока рекурсія біля межі стека може викинути
Errorпри перевищенніzend.max_allowed_stack_size(мінус резерв); для fibers враховуєтьсяfiber.stack_size. - Zend Max Execution Timers за замовчуванням увімкнені для ZTS-збірок на Linux — стежте за довгоживучими CLI-воркерами.
Процеси
proc_get_status()на POSIX повертає коректні значення при повторних викликах; результат може кешуватися (ключ"cached").proc_close()післяproc_get_status()тепер дає коректний код виходу (не-1).
Масиви й трейти
- Видимість констант класу: при успадкуванні з інтерфейсів тепер перевіряється variance — код із м’якшою видимістю може потребувати виправлень.
- Порожній масив + від’ємний перший індекс: наступний неявний ключ —
n+1(не0). - Трейти зі static-властивостями: успадковані static у батька переоголошуються для кожного класу, що використовує трейт (окреме сховище) — може зачепити тонкий static-стан.
Стандартна бібліотека (високий ризик)
range(): суворіша валідація (TypeError/ValueErrorдля поганих входів), більше попереджень на дивних межах, інша поведінка для символьних діапазонів, коли межі виглядають числовими — переперевірте код, де діапазони будуються з користувацького вводу.number_format(): від’ємний$decimalsтепер округлює до десяткової крапки (раніше ігнорувалося).file(): некоректні комбінації прапорів відхиляються (наприкладFILE_APPENDраніше мовчки приймався).
Date / DOM / FFI / Opcache
- Date: виразніші ієрархії
DateError/DateExceptionзамість загальних попереджень/винятків — оновітьcatch. - DOM: поведінка ближче до специфікації для вузлів без батька; виправлення
createAttributeNS(); нові члени можуть конфліктувати з користувацькими підкласами — перевірте сумісність сигнатур. - FFI:
voidC-функції повертаютьnull, а не фіктивний об’єктFFI\CData:void. - Opcache:
opcache.consistency_checksвидалено (був несумісний із tracing JIT / кешем успадкування).
WeakMap
- Самореферентні ключі в
WeakMapможуть збиратися в циклах, де досяжність лише через ітерацію — перегляньте екзотичні кеші.
Deprecated (інкремент/декремент рядків, get_class(), assert INI)
Рядкові ++ / --
Інкремент/декремент для порожніх або нечислових рядків позначено deprecated; нечисловий інкремент — «м’який» deprecated. Для нового коду краще str_increment() / str_decrement().
get_class() / get_parent_class() без аргументів
Виклик без аргументів — deprecated — передавайте об’єкт або ім’я класу явно.
Assert
assert_options()і пов’язані константи — deprecated.- INI-налаштування
assert.*— deprecated; міграція описана в розділі migration 8.3 про обробку INI.
Інше
- Reflection:
ReflectionProperty::setValue($value)(один аргумент) для static-властивостей deprecated — для static передайтеnullяк об’єкт. - SQLite3: краще винятки;
enableExceptions(false)дає deprecation. - Random: варіант
MT_RAND_PHP— deprecated.
Інші зміни та експлуатація (gc_status, streams, highlights)
gc_status()повертає більше полів за часом (collector/destructor/free) — корисно під час налаштування пам’яті.- Streams:
fread()на сокетах може повернути раніше за наявності даних у буфері; memory streams поводяться ближче до файлів при seek за кінець. open_basedir: runtimeini_setвідхиляє шляхи з..навіть з префіксом./.- highlight_string/file: змінилася структура HTML — оновіть знімки тестів, якщо порівнюєте підсвічування построчно.
Підсумок
PHP 8.3 вигідний тим, хто вважає константи й override частиною типового контракту: типізовані константи й #[\Override] зменшують «тихий дрейф» під час рефакторингу. Доповніть це json_validate для дешевої перевірки й чітким планом щодо рядкового інкременту та assert — саме там найчастіше дивується legacy-код.