PHP 8.0: What's New and Changed
PHP 8.0 is a major version update and a remarkable milestone in PHP, as it brings several new features to type system, syntax, error handling, strings, object-oriented programming, and more.
It is the efforts of hundreds of people coming together to shape the future of a programming language that powers a significant portion of the Internet web sites and applications.
PHP tries to be conservative with changes that can break a majority of the applications, and yet, it brings several new major features to PHP 8.0.
Features such as Named Parameters, JIT, Attributes, and Constructor Properties bring major improvements and syntax changes, while several minor improvements such as resource to object migrations, improved error handling, and changes and improvements in operators and engine comparisons help seamlessly reduce the chances of overlooked bugs.
Thank you for all the contributors, of whom there are hundreds, for all your efforts, in PHP core, documentation, libraries, testing tools, extensions, authors, package maintainers, PHP developers, and everyone else including you ❤.
Major New Features
Named Parameters
PHP 8.0 allows named parameters in function/method calls in addition to traditional positional parameters.
This makes the function/method parameter names part of the public API. The non-standardized DocBlock @no-named-arguments expresses that the library does not provide backwards-compatibility for named parameters.
Attributes
Attributes allows declaring meta-data for functions, classes, properties, and parameters. Attributes map to PHP class names (declared with an Attribute itself), and they can be fetched programmatically with PHP Reflection API.
Attributes makes it easy and performant to declare Attributes/annotations that previously required storing them in DocBlock comments, and parsing the string to infer them.
Constructor Properties
A new syntax to declare class properties right from the class constructor ( __construct magic method).
In the constructor, PHP 8.0 supports declaring the visibility ( public , private , or protected ) and type. Those properties will be registered as class properties with same visibility and type they are declared in the constructor.
This backwards-incompatible feature can help reduce boilerplate code when declaring value-object classes.
Just-In-Time Compilation
PHP Opcache supports JIT. It’s disabled by default, and if enabled, JIT compiles and caches native instructions. It does not make a noticeable difference in IO-bound web applications, but provides a performance boost for CPU-heavy applications.
Note that JIT is still new, and had bug fixes as late as a day before PHP 8.0.0 release. It makes debugging and profiling more difficult with the added extra layer.
Union Types
Union Types extend type declarations (return types, parameters, and class properties) to declare more than one type.
It also supports false as a special type (for Boolean false ), a trait that’s prevalent in legacy code that did not use Exceptions.
Null-safe Operator
Null-safe operator provides safety in method/property chaining when the return value or property can be null .
The ?-> null-safe operator short-circuits the rest of the expression if it encounters a null value, and immediately returns null without causing any errors.
match expressions
Match expressions are similar to switch blocks, but match blocks provide type-safe comparisons, supports a return value, does not require break statements to break-out, and supports multiple matching values. it also guarantees that at least one branch is matched, ensuring all cases are accounted for.
Not all switch blocks might convert well to match blocks. Code that requires backwards-compatibility, switch blocks with multiple statements (as opposed to single-line expressions), or expects fall-through functionality still fits the switch statements.
WeakMaps
A WeakMap allows to store and associate arbitrary values for object keys, but without preventing the garbage collector from clearing it the object falls out of scope in everywhere else.
A WeakMap is similar to SplObjectStorage , as in both WeakMap and splObjectStorage use objects s as the key, and allows storage of arbitrary values. However, a WeakMap does not prevent the object from being garbage collected.
New Functions and Classes
PHP 8.0 introduces a few new functions to ease string inspections (contains, starts with sub-string, or ends with sub-string) to replace the meticulous strpos() !== false calls that are less readable, and error-prone due to weak type comparisons.
Function | Description | Example |
---|---|---|
str_contains | Haystack contains the needle somewhere | str_contains(‘Foobar’, ‘Foo’) |
str_starts_with | Haystack starts with the needle string | str_starts_with(‘PHP 8.0’, ‘PHP’) |
str_ends_with | Haystack ends with needle string | str_ends_with(‘PHP 8.0’, ‘8.0’) |
Function | Description |
---|---|
fdiv | Float division supporting IEEE-754 standard on Floating-Point Arithmetic. |
get_resource_id | Returns the internal ID for a given PHP resource |
get_debug_type | Returns the internal type of a passed variable |
preg_last_error_msg | Returns a human-friendly error message for the last preg operation. |
New Stringable interface
The new Stringable interface is automatically added to all classes that implement __toString method, and those explicitly declare that they implements Stringable .
With the Stringable interface, it is now easy to declare types as string|Stringable for on functions that can accept/return strings or objects with a __toString() method.
New PhpToken Tokenizer class
The new PhpToken class provides a more fluent Object-Oriented interface as an alternative to the legacy array-based to token_get_all function.
Type System Improvements
PHP 8.0 improves typing system with the addition of Union Types and the mixed type.
Union Types
Union Types extend type declarations (return types, parameters, and class properties) to declare more than one type.
It also supports false as a special type (for Boolean false ), a trait that’s prevalent in legacy code that did not use Exceptions.
New mixed pseudo type
PHP 8.0 brings mixed type, that was already being widely used in DocBlock comments.
mixed type can be used to indicate that it accepts any type, or can return any type. In a class/interface context, mixed type plays by the same rules of Liskov Substitution Principle.
static return type for class methods
static return type, already support as a DocBlock return type, is now supported in PHP 8.0. The static return type declares an object of the called class will be returned.
Error Handling Improvements
A major and backwards-incompatible change in PHP is that internal functions now throw exceptions on type errors or value errors.
This corrects PHP’s historical behavior of emitting a warning, and returning null when it encounters a value that it cannot use. This behavior is often undesired because PHP warnings does not halt the execution of the remaining block.
Internal function warnings now throw TypeError and ValueError exceptions
Almost entirety of PHP internal functions now enforce type checking, and instead of warnings, PHP now throws TypeError or ValueError exceptions. On legacy code bases, this change can cause issues, now that the errors are more boldly and unforgivably handled.
throw in expressions
Prior to PHP 8.0, it was not possible to throw exceptions from an expression (e.g a ternary statement). This is now allowed in PHP 8.0.
catch exceptions only by type
It is possible to catch exceptions by their type, without capturing the exception object.
Default error reporting is set to E_ALL
PHP 8.0 default configuration is to show all error messages by default. It was configured to hide deprecation and strict warnings in older versions.
PHP Startup Errors are displayed by default
PHP now displays startup-errors (failure to load dynamic extensions, invalid INI configurations, etc) by default.
Assertions throw exceptions by default
PHP assertions ( assert() ) now throw exceptions on assertion failures. Prior to PHP 8.0, it required an explicit configuration that was disabled by default.
@ Error Suppression operator does not silent fatal errors
PHP 8.0 corrects the behavior of @ error suppression operator, where it silenced fatal errors, which lead to a script failure, because the @ operator does not prevent fatal errors, but rather hide the error message display.
Resource to Object Migration
One of the long-term efforts in PHP development was to move away from the resource types. They were difficult to deal with, and even in PHP 8.0, does not offer typing support.
PHP resource objects do not play well with garbage-collector well either, which resulted in memory leaks in resource objects such as xml .
In PHP 8.0, some of the most used extensions changes moves away from the traditional resource objects to standard PHP classes.
In PHP 8.0, they are work as value-objects as opposed to fully-features classes with methods in them. Majority of these classes do not allow instantiating with the new Foo() construct either, and must be instantiated with the existing functions that returned resource objects in prior versions.
PHP 8.0’s resource to object migration is quite seamless, as in all functions return and accept the new objects, and behave by the same semantics of the previous resource objects.
Extension | resource (PHP < 8.0) | object (PHP >= 8.0) |
---|---|---|
Curl | Curl | CurlHandle |
Curl | curl_multi | CurlMultiHandle |
Curl | curl_share | CurlShareHandle |
GD | gd | GdImage |
Sockets | Socket | Socket |
Sockets | AddressInfo | AddressInfo |
OpenSSL | OpenSSL key | OpenSSLAsymmetricKey |
OpenSSL | OpenSSL X.509 | OpenSSLCertificate |
OpenSSL | OpenSSL X.509 CSR | OpenSSLCertificateSigningRequest |
XMLWriter | xmlwriter | XMLWriter |
XML | xml | XMLParser |
PHP Object Oriented Programming changes
PHP 8.0 is the first major version to be strict on Liskov Substitution Principle violations. Prior to PHP 8.0, PHP was not consistent on how it handled incompatible method signatures.
In PHP 8.0, all signature mismatches, including abstract traits, result in a fatal error. Further, it enforces signatures for PHP magic methods.
Fatal errors on incompatible method signatures
PHP 8.0 throws fatal errors when Liskov Substitution Principle is not followed when classes are extended, or interfaces are implemented.
Prior to PHP 8.0, incompatible signatures only emitted a warning.
Class magic method signatures are strictly enforced
From PHP 8.0 and later, magic methods (e.g __toString() , __get() , etc), if they declare types, must implement the signature PHP expects. This is to avoid the smallest chance of the user declaring a magic method that doesn’t follow the semantic meaning.
Declarations like Foo::__toString(): object was allowed in previous PHP versions, but PHP 8.0 and throws an exception if the signature does not meet the requirements.
Calling non-static class methods statically result in a fatal error
PHP 8.0 no longer allows calling class methods as a static method.
Previous versions emitted a deprecation notice, but from PHP 8.0 and later, this results in a fatal error.
Inheritance rules are not applied to private class methods
PHP 8.0 relaxes the signature, abstract , and static flag enforcement for private class methods. This change comes from the rationale that private methods are just that: Private.
From PHP 8.0, it is now allowed for the child classes to declare abstract methods, and change static/flags for private methods.
::class magic constant is now supported on objects
The ::class magic constant returns the fully-qualified class name. This was only allowed on class names (such as Foo\Bar::class ), but in PHP 8.0, the ::class magic constant works on instantiated objects too.
String-related changes
In PHP 8.0, there are several subtle changes that might be not obvious at first, but can result in quite unexpected results.
A major difference in PHP 8.0 is that, PHP now considers there is an empty string between every character in a given string.
Prior to PHP 8.0, checking for an empty string needle ( «» ) was not allowed, but in PHP 8.0, PHP will happily accept it, and return that there is indeed an empty string between each character.
The multi-byte handling, or functions like strlen still returns same values as the older versions, but all functions that check for a substring in a given string are changed.
In addition, PHP 8.0 changes how the string concatenation operator priorities, and supports new modifiers in sprintf functions such as %h and %H modifiers and * width and precision modifier.
substr , iconv_substr , grapheme_substr return empty string on out-of-bound offsets
These functions clamp the needle and offset parameters to the string length, and returns an empty string instead of returning false .
+ / — operators take higher precedence when used with concat ( . ) operator
When the mathematical + and — operators are used in the same expression with the concatenation operator ( . ), the + and — operators take higher precedence. This resulted in a deprecation notice in PHP versions prior to 8.0, but now it happens silently and as per the warning.
Locale-independent float to string casting
When a float value is coerced to string , PHP no longer uses the locale. Prior to PHP 8.0, PHP considered the current locale (which is not thread-safe) or system locale when doing so. This resulted in inconsistent string outputs because certain locales, specially European ones, swap the thousand separator and decimal sign from the US locale.
For locale-aware float to string cast, the %f modifier in printf class of functions can be used.
In addition, the new %h and %H modifiers for printf class of functions provide locale-indepdent variants of %g and %G modifiers.
$thanks ❤
PHP 8.0 is an amazing effort from hundreds of awesome people. It’s a major milesone in PHP’s history. Thank you to everyone who helped from code, to documentation, to conferences, to articles to all of the developers.
Вышел PHP 8: обзор изменений языка
Вышла стабильная версия PHP 8, бинарные файлы, в том числе для Windows, уже доступны для скачивания.
Что нового в PHP 8
Выпуск содержит крупные изменения в языке PHP, рассмотрим их.
PHP 8.0 содержит множество улучшений и новых функций, таких как:
- Типы Union
- Именованные аргументы
- Выражения match
- Атрибуты
- Constructor Property Promotion
- Оператор Nullsafe
- Weak Maps
- Just In Time Compilation
- И многое другое…
Именованные аргументы
Указывайте только обязательные параметры, пропуская необязательные.
Аргументы не зависят от порядка и самодокументированы.
Атрибуты
Вместо аннотаций PHPDoc теперь вы можете использовать структурированные метаданные с собственным синтаксисом PHP.
Продвижение свойств конструктора RFC Doc
Меньше шаблонного кода для определения и инициализации свойств.
Типы Union RFC Doc
Вместо аннотаций PHPDoc для комбинации типов вы можете использовать собственные объявления типа union, которые проверяются во время выполнения.
Выражения match RFC Doc
Новый match похож на switch и имеет следующие особенности:
- match — это выражение, то есть его результат может быть сохранен в переменной или возвращён.
- Ветви соответствия поддерживают только однострочные выражения и не требуют указания break;
- match делает строгие сравнения.
Оператор Nullsafe RFC
Вместо нулевых (null) условий проверки теперь вы можете использовать цепочку вызовов с новым nullsafe оператором. Когда оценка одного элемента в цепочке завершается неудачно, выполнение всей цепочки прерывается, и вся цепочка принимает значение null.
Более разумное сравнение строки и числа RFC
При сравнении с числовой строкой PHP 8 использует сравнение чисел. В противном случае он преобразует число в строку и использует сравнение строк.
Ошибки согласованного типа для внутренних функций RFC
Большинство внутренних функций теперь выдают исключение Error, если проверка параметров не выполняется.
Компиляция Just-In-Time
PHP 8 представляет два механизма JIT-компиляции. Tracing JIT, наиболее многообещающая из двух, показывает примерно в 3 раза лучшую производительность на синтетических тестах и в 1,5–2 раза на некоторых конкретных долго работающих приложениях. Типичная производительность приложения на уровне PHP 7.4.
PHP 8 — что нового в 8-ой версии php
Оглавления для удобной навигации по новым PHP 8.0 фичам (клик для перехода):
- Новые строковые функции
- Named Arguments
- Constructor property promotion
- Match expression
- Union types
- Attributes
- Nullsafe operator
1. Новые нативные функции для работы со строками
str_contains — для проверки есть ли подстрока в строке.
str_contains(string $haystack, string $needle): bool
str_starts_with, str_ends_with — функции для проверки "начинается ли строка с" и "заканчивается ли строка на"
str_starts_with(string $haystack, string $needle): bool
str_ends_with (string $haystack, string $needle): bool
2. Named arguments
Теперь можно использовать именованные аргументы. Это может быть полезно, например, когда функция имеет много необязательных аргументов, но нам они не важны и нам важно передать только последний из аргументов.
В PHP < 8 мы бы вызывали так:
3. "Constructor property promotion" или просто "Constructor promotion"
Для меня, это одна из самых полезных фичей новой версии, которая позволяет экономить время разработки и рефакторинга.
Прямо в конструкторе можно указать модификтор доступа любого аргумента будь то private / protected / public , тогда property с таким именем можно нужно не объявлять вовсе. Как можно заметить, никакое присваивание в теле конструктора тоже не нужно, наличие модификатора доступа в конструкторе PHP 8.0 — автоматически создает проперти с именем, равным именем переменной и присваивает параметр в property.
В версиях PHP < 8 мы бы писали так (почти в 3 раза! больше кода!):
Используя DI, autowiring и constructor promotion — теперь сплошное удовольствие при подстановке зависимостей в сервис.
4. match expression
Match expression (см. https://www.php.net/manual/en/control-structures.match.php) — более емкий и читаемый вариант для оператора switch . Есть и отличие от switch : match всегда использует строгое сравнение. Отпадает необходимость в break.
Итого про match:
не любой switch можно заменить на match . Вместо простых switch можно использовать более читаемый и емкий match .
5. Union types
В этом случае в проперти $this->city можно будет присовить только типы false, null или объект City.
То, что раньше описывали c помощью phpdoc /** @var false|null */ теперь можно легально описать языковой конструкцией.
Кроме types properties, Union types можно использовать как в аргументах, так и в возвращаемых значениях.
Лучше не увлекаться Union types в PHP, так как все таки это не однозначность в типах.
6. Attributes PHP 8.0 feature
Аттрибуты — фича, которая позволяет использовать языковую конструкцию для добавления мета-данных к классу, функции, проперти. Проблема, которую решают аттрибуты — зависимость кода от PHPDoc комментариев, что очень широко используется в doctrine, symfony и тд. Теперь выполнение кода может зависеть от аттрибутов:) которые являются языковой конструкцией, то есть это более "стандартизированный" подход.
Аттрибуты в PHP объявляются с помощью символов #[ и ]
По поводу синтаксиса аттрибутов было много споров. В PHP все что начинается с # является комментарием. Это значит, что синтаксис аттрибутов #[ не будет вызывать синтаксическую ошибку на более ранних версиях PHP (до PHP 8.0). То есть код с аттрибутами запустится и на более ранних версиях языка, чем когда аттрибуты стали поддерживаться (с PHP 8.0). Другой вопрос, станет ли код на ранних версиях работать ожидаемо:)
PHP 8.0: Nullsafe operator feature
Проверка на null при вызове методов может быть осуществлена прямо в вызове с помощью добавления знака ? (вопрос): ?->
Если один из объектов в цепочке вызов выше будет null , то в переменную запишется null
Sorry, you have been blocked
This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.
What can I do to resolve this?
You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.
Cloudflare Ray ID: 7d3e2e2a4968c2ff • Your IP: Click to reveal 138.199.34.4 • Performance & security by Cloudflare