PHP 8.5: Основни нововъведения
PHP 8.5 продължава линията „повече изразителност в езика“: pipe оператор (|>), #[\NoDiscard] срещу игнорирани връщани стойности и closures в константни изрази за атрибути и default стойности. На платформено ниво — винаги включено URI разширение, по-строг filter и сериозни промени в PDO / Opcache: заложете QA не само за синтаксис, а и за разширения, сборка и INI.
Съдържание
- Pipe оператор (
|>) - Closures и first-class callable в константни изрази
#[\NoDiscard]и(void)cast- URI разширение (RFC 3986 / WHATWG URL)
- Бележки по библиотеки и разширения
- Нови функции (
array_first,array_last, handlers, …) - Практични рецепти
- Обратно несъвместими промени (миграционни бележки)
- Deprecated (чеклист)
- Други промени и експлоатация (Opcache, INI, производителност)
Pipe оператор (|>)
Операторът pipe подава стойността отляво в callable с един параметър отдясно. Удобен е за вериги от трансформации без междинни променливи.
$result = 'Hello World' |> strlen(...);
// Същото като: $result = strlen('Hello World');
Правила, които „хапят“: отдясно трябва да е callable с точно един параметър (и не by-ref). Ако отдясно не е валиден callable — хвърля Error. Arrow functions трябва да са в скоби при |> заради синтактична двусмисленост. Вижте functional operators.
Closures и first-class callable в константни изрази
В PHP 8.5 closures и first-class callable са позволени в константни изрази, включително:
- аргументи на атрибути;
- default стойности на свойства и параметри;
- константи и константи на клас.
Това помага, когато искате метаданни/дефолти да сочат към реален callable, а не към „магически“ низове.
#[\NoDiscard] и (void) cast
#[\NoDiscard] маркира функции/методи, чиято върната стойност не е желателно да се игнорира.
(void) изрично казва „зарязвам намерено“. Не променя runtime само по себе си, но може да потисне предупреждения, свързани с #[\NoDiscard].
#[\NoDiscard]
function loadConfig(): array { return []; }
(void) loadConfig();
Практически: маркирайте резултати, които са лесни за „забравяне“ (builder-и, валидатори, функции, връщащи bool/Result), за да не се изпълнява код „на празно“.
URI разширение (RFC 3986 / WHATWG URL)
PHP 8.5 добавя винаги включено разширение uri за URI/URL по RFC 3986 и WHATWG URL. Полезно за коректно парсване вместо ad hoc низови операции.
Бележки по библиотеки и разширения
- Filter:
FILTER_THROW_ON_FAILURE— при грешка може да се хвърли изключение (не се комбинира сFILTER_NULL_ON_FAILURE). - Intl: напр.
IntlListFormatter,Locale::addLikelySubtags()/minimizeSubtags(), допълнителни константи наNumberFormatterза валути (зависи от ICU). - Session / cookies:
session_set_cookie_params(),session_get_cookie_params(),session_start(),setcookie()/setrawcookie()— ключ"partitioned"за partitioned cookies. - Standard: по-добри грешки при
mail()с sendmail;getimagesize()— HEIF/HEIC, SVG (с libxml), метаданни за единици. - DOM: напр.
Dom\Element::$outerHTML,$childrenприDom\ParentNode. - cURL: нови ключове/опции за
curl_getinfo/curl_setopt(често изискват по-нова libcurl).
Нови функции (array_first, array_last, handlers, …)
- Core:
get_error_handler(),get_exception_handler(),Closure::getCurrent() - Standard:
array_first(),array_last() - Reflection, Opcache, PGSQL/SQLite/DOM — вижте new functions
Практични рецепти
Pipe верига за нормализация
$slug = $raw
|> trim(...)
|> strtolower(...)
|> preg_replace('/\s+/', '-', ...);
Filter с изключение вместо false
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, FILTER_THROW_ON_FAILURE);
Първи/последен елемент без ръчно индексиране
$first = array_first($list);
$last = array_last($list);
Partitioned cookies (където е приложимо)
setcookie('sid', $sid, [
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'None',
'partitioned' => true,
]);
Обратно несъвместими промени (миграционни бележки)
Ядро
class_alias(): забранени имена"array"и"callable".- Слабо сравнение с bool за „несравними“ обекти — унифицирано с
(bool)$object. gc_collect_cycles(): връщаната стойност вече не брои косвено събрани низове/ресурси.- Final подкласове: по-гъвкаво заместване на
staticсselfили конкретен клас. - Tick handlers: след shutdown, деструктори и output handlers.
- Трейтове: променен ред на binding спрямо родител.
- Грешки при компилация/линкване: променен ред на обработка.
#[\Attribute]върху abstract class, enum, interface, trait: грешка при компилация, освен ако не се ползва#[\DelayedTargetValidation].disable_classes: премахната INI.- Деструктуриране не-масив/не-null с
[]/list()— предупреждение. - int cast извън диапазон и NAN — предупреждения.
Opcache
- Винаги вграден в бинарника;
zend_extension=opcache.soпредупреждава. Актуализирайте deployment документация.
PDO
- Променени числови стойности на
PDO::FETCH_*за част от флаговете. FETCH_CLASSctor args: семантика катоcall_user_func_array.- Ограничения за
FETCH_PROPS_LATE,FETCH_INTO+fetchAll()и др.
DOM / SPL / др.
- Клониране на live
NodeList/NamedNodeMap→ неуспех. ArrayObject: без enum елементи.- mysqli: повторен конструктор → Error.
- Много места вече хвърлят
ValueErrorвместоTypeError/warnings (напр. Bzip2bzcompress()диапазони, LDAP invalid option, SNMP хост/порт, sockets портове, FileInfo nul bytes и т.н.) — QA за „входове от потребител“ е задължителен.
Deprecated (чеклист)
Тук е „какво да чистите рано“, преди да стане hard error в следващи версии. Пълен списък: migration85 deprecated.
Core
- Output в user output handler е deprecated (за да се вижда deprecation-ът, съобщението заобикаля handler-а).
- Неканонични cast имена
(boolean),(integer),(double),(binary)→ използвайте(bool),(int),(float),(string). caseсъс;вместо:е deprecated.- Backticks като alias за
shell_execса deprecated. __debugInfo()да връщаnullе deprecated → върнете[].report_memleaksINI е deprecated.- Redeclare на константи е deprecated (и остава warning).
- Closure binding „аномалии“ (binding на static closure към instance, unbinding
$this, rebind scope към internal клас, и т.н.) са deprecated. __sleep()/__wakeup()са soft-deprecated → мигрирайте към__serialize()/__unserialize().nullкато array offset или къмarray_key_exists()е deprecated.- Инкрементиране на не-числови низове е deprecated → използвайте
str_increment(). register_argc_argvderivation от query string за не-CLI SAPIs е deprecated.
Extensions / standard library
- cURL:
curl_close()иcurl_share_close()deprecated (handle-ите се освобождават автоматично). - FileInfo:
finfo_close()deprecated;$contextнаfinfo_buffer()deprecated. - GD:
imagedestroy()deprecated (GdImage се освобождава автоматично). - XML:
xml_parser_free()deprecated (XMLParser се освобождава автоматично). - Random/strings: някои „старо поведение“ се чисти агресивно — планирайте refactor-и преди 8.6/8.7.
PDO
uri:DSN е deprecated (риск при remote URIs).- Driver-specific константи и методи в базовия
PDOса deprecated → използвайтеPdo\\*класовете (Pdo\\Mysql::...,Pdo\\Pgsql::..., и т.н.).
Други промени и експлоатация
- CLI:
--ini=diff;cli_set_process_title()при твърде дълго заглавие — неуспех. - FPM:
fastcgi.script_path_encodedза управление на decoding на script path при ProxyPass;log_limitвлияе на access log limit. - Core:
hrtime()на macOS използва препоръчителен API. - INI:
fatal_error_backtraces,max_memory_limit, ограничения заmemory_limit. - Opcache:
opcache.file_cache_read_only, настройки на JIT, коректно отчитане на памет. - Производителност: по-бързи изключения, масивни колбеци, Reflection, SIMD, TAILCALL VM с Clang ≥ 19 — вижте other changes.
Обобщение
PHP 8.5 комбинира по-четим синтаксис и по-строга платформа. Тествайте PDO режими, cookies/session, код със стари close помощници и слабо сравнение обект ↔ bool.