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 още при компилация
Маркирайте методи, които трябва да 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'); // стъпка без string ++
$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 build-ове на Linux — внимавайте с дълго живеещи CLI worker-и.
Процеси
proc_get_status()на POSIX връща коректни стойности при повторни извиквания; резултатът може да се кешира (ключ"cached").proc_close()следproc_get_status()вече дава коректен exit code (не-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 структурата — обновете snapshot тестове, ако сравнявате подсветката.
Обобщение
PHP 8.3 помага на екипи, които третират константите и override като част от типовия договор: типизираните константи и #[\Override] намаляват „тихия дрейф“ при рефакторинг. Комбинирайте с json_validate за евтина валидация и ясен план за низов инкремент и assert — там legacy кодът най-често се изненадва.