decorative image for blog regarding PHP 8.2
March 29, 2023

PHP 8.2: Key Features and Changes

PHP Development
Modernization

PHP 8.2 released on December 8, 2022, and it brought with it a range of new features, breaking changes, and deprecations that developer teams must be aware of. With PHP 8.1 EOL approaching at the end of 2025, many teams are considering their PHP 8.2 upgrade options.

In this blog, we discuss the PHP 8.2 release, including the PHP 8.2 release date, and this PHP version's key features, improvements, and deprecations. Let's get started

Back to top

PHP 8.2 Release Date

The PHP 8.2 release date was on December 8, 2022.  

PHP 8.2 underwent three alpha releases, three beta releases, and six release candidates before it reached general availability.

PHP 8.2 Release Stage

Date

Alpha 1

Jun 09 2022

Alpha 2

Jun 23 2022

Alpha 3

Jul 07 2022

Beta 1

Jul 21 2022

Beta 2

Aug 04 2022

Beta 3

Aug 18 2022

Release Candidate 1

Aug 04 2022

Release Candidate 2

Sep 15 2022

Release Candidate 3

Sep 29 2022

Release Candidate 4

Oct 13 2022

Release Candidate 5

Oct 27 2022

Release Candidate 6

Nov 10 2022

General Availability

Dec 8 2022


PHP 8.2 Support Lifecycle 

As the PHP 8.2 release date was December 8, 2022, PHP 8.2 will be supported until December 31, 2026 which is 4 years from the day of release, with active support until December 8 2024, and security support until December 31, 2026. It is currently only receiving security support from the community. To access full support, teams will need to partner with an experienced third party for long-term support (LTS) services.

Branch

GA Release

Active Support (Community)

Security Support (Community)

PHP 8.2

December 8, 2022

December 8, 2024

December 31, 2026


When Does PHP 8.2 End of Life Begin?

PHP 8.2 end of life will occur after December 31, 2026. 

After PHP 8.2 EOL is reached, this version will not receive any new patches. Teams will need to migrate to a supported PHP version, such as PHP 8.3 or PHP 8.4, to ensure mission-critical applications remain secure.

PHP 8.2 Support From a Global Team of Experts

Zend Long Term Support (LTS) keeps your apps secure through 2028 with patched PHP 8.2 builds and migration support. Upgrade on your schedule, maintain compliance standards, and access 24/7/365 support.

Explore lts Options  See Migration Services

 

Back to top

PHP 8.2 Features

PHP 8.2 introduced a number of new features and improvements, as well as some breaking changes and deprecations to watch out for. The full list of changes is available at php.net.

PHP 8.2 adds a few nice quality of life improvements for PHP developers, including readonly classes, a new random number generator (RNG), disjunctive normal form (DNF) types, Sensitive Parameter value redaction, and a ton of other features.

Readonly Classes in PHP 8.2

Readonly properties were added in PHP 8.1, but needed improvements for declaring immutable classes with many properties. The ability to define readonly classes added in PHP 8.2 allows developers to implicity mark all instance properties of a class as readonly while preventing the creation of dynamic properties.

New Random Number Generator 

While random number generators might not be the most exciting feature, this improvement is a great big picture improvement for PHP, because RNGs form the basis for most security features. 

DNF Types 

PHP 8.0 provided the language with union types (e.g. “array|Traversable”, indicating the type must satisfy one OR the other type), while PHP 8.1 provided the language with intersection types (e.g. “Countable&Traversable”, indicating the type must implement BOTH the Countable AND Traversable interfaces). However, you could not combine them. 

PHP 8.2 allows you to combine union and intersection types using notation following Disjunctive Normal Form (DNF). At its most basic, it means describing the allowed types as an OR’d series of ANDs. As an example, if you wanted to accept an object that was stringable and callable, or an object that is countable and traversable, you could write the type description as “(Stringable&callable)|(Countable&Traversable)”.

Sensitive Parameter Value Redaction

When debugging an application, it’s possible for a stack trace generated by an exception to reveal sensitive data such as credentials, particularly when the values are received as function arguments. A new feature in PHP 8.2 allows masking those values so that they do not end up in the stack trace. 

You can mark a sensitive parameter using an attribute, “#[\SensitiveParameter]”. As an example, if you do not want the password passed to a function to be revealed in the stack trace, you could write your function signature as follows:

function connect(string $user, #[\SensitiveParameter] string $password): bool

Any stack trace generated within that function would note SensitiveParameterValue instead of the actual value, preventing information disclosure.

The previous features are some of the more notable, as they represent significant additions to the language. However, there were quite a number of additional features in this release, including:

  • You can now define constants in traits
  • Each of “null”, “false”, and “true” are now standalone types
  • Introduction of mysqli_execute_query/mysqli::execute_query, which combine creation of a statement and execution of it into a single function/method
  • An ini_parse_quantity() function, to allow verification that a quantity will work with php.ini rules
  • Addition of a curl_upkeep() function, allowing you to keep a curl connection alive 
Back to top

Notable PHP 8.2 Deprecations

Every new PHP minor release brings with it new deprecations and minor functionality changes that can lead to issues when upgrading. The following details what to look out for in PHP 8.2.

Dynamic Properties in PHP 8.2

Dynamic properties have been the default behavior of PHP classes since they were first introduced to the language; you likely have used them without even realizing that it was a distinct behavior. 

Essentially, PHP classes allow you to define arbitrary properties on a class instance without having them declared by the class first. For example, the definition “class Dynamic {}”, when instantiated, allows you to call “$instance->foo = “bar””, which will define a “foo” property with value “bar”, and this will not raise any errors. You can later access the “foo” property, and receive back the value you assigned. 

As PHP has moved towards stricter typing and more explicit definitions and specifications, this behavior has come increasingly into question. In addition, many of the changes made to internals to provide features such as opcaching and the JIT compiler makes the usage of dynamic properties increasingly a liability. 

As such, as of PHP 8.2, usage of dynamic properties is now deprecated, with the exception of: 

  • stdClass and its subclasses (which is what json_decode() creates)
  • Classes that define “__set()” (which will likely need to be coupled with “__get()” to be useful)Classes that declare the “#[\AllowDyamicProperties]” attribute. If you haven’t heard of this attribute before, it’s because it was introduced with PHP 8.2 specfically for this purpose.

f you have a class where usage allows or requires dynamic properties, you will need to start using the “#[\AllowDynamicProperties]” attribute to ensure it remains compatible in future PHP versions. 

utf8_encode() and utf8_decode()

This pair of functions has been around since very early versions of PHP, and were used to convert strings to UTF-8. However, there’s a little hitch: they only convert from ISO-8859-1 (aka Latin 1 encoding). Many users are unaware of this limitation, and use it to convert from other encodings, which can lead to invalid conversions. 

PHP 8.2 deprecates the functions. You can use functions from the iconv, mbstring, or intl extensions to achieve the same results, and, in most cases, get a better range of conversions.

This article on php.watch goes into some detail on how to adapt your code.

Partially-Supported Callables

PHP has had a variety of syntaxes over the years to denote callables, and maintainers have put a lot of work in over the last several versions to make them more consistent. As of the PHP 8 series, you can generally invoke “$callable(/* parameters */)” on a callable, and expect it to work. 

However, in practice, it turns out there are a number of callable patterns that the PHP engine can only resolve if the context is valid where invoked: 

  • self::method and [“self”, “method”]
  • parent::method and [“parent”, “method”]
  • static::method and [“static”, “method”]
  • [“ClassName”, “ClassName::method”]
  • [new ClassName(), “DifferentClass::method”] 

As such, PHP 8.2 will now raise a deprecation notice when invoking one of these callable patterns. However, they are still considered valid for purposes of typehints. 

If you are using these patterns, use Closure::fromCallable() to create a version bound to the creation context that can be passed around and used everywhere.

Mbstring Extension Changes

The multi-byte string (mbstring) extension allows manipulating multi-byte strings, and supports conversions to and from different encodings. 

Four encodings mbstring has always supported, however, work on raw bytes instead of byte sequences, which leads to unexpected and often invalid conversions. These inlucde the Base64, Quoted-Printable, Uuencode, and HTML Entities encodings. 

Starting with PHP 8.2, mb_detect_encoding and mb_convert_encoding will no longer work with these encodings. 

If you depended on this functionality, you can adapt your code as follows: 

  • “mb_convert_encoding($string, ‘base64’)” should become “base64_encode($string)”
  • “mb_convert_encoding($encodedString, $originEncoding, ‘Base64’)” should become “base64_decode($encodedString)”
  • “mb_convert_encoding($encodedString, ‘HTML-Entities’, $originEncoding)” should become “htmlentities($encodedString)”. If you need to convert from one encoding to another and then prepare HTML entities, use “mb_convert_encoding($string, $targetEncoding, $originEncoding)” before calling “htmlenentities()”.
  • “mb_convert_encoding($string, ‘UUENCODE’)” should become “convert_uuencode($string)”
  • “mb_convert_encoding($string, $targetEncoding, ‘UUENCODE’)” should become “convert_uudecode($string)”
  • “mb_convert_encoding($string, ‘Quoted-Printable’)” should become “quoted_printable_encode($string)”
  • “mb_convert_encoding($string, $targetEncoding, ‘Quoted-Printable’)” should become “quoted_printable_decode($string)” 
Back to top

PHP 8.2 Changes

${var} string interpolation 

String interpolation is the practice of injecting variable content within a string. The most common way to do this is with double quotes:

echo “Hello $name”;

Sometimes it’s useful to surround the variable with curly braces, as this can make the variable stand out better, and also allows easier usage of pattern matching to locate such strings:

echo “Hello {$name}”;

Another less-used syntax uses the form “${…}”: 

echo “Hello $(name}”; 

This style usage derives from other languages (it’s used in shell scripting heavily), but had one particular advantage with PHP: the value inside the curly braces could be an expression, which meant that you could use ternaries, instance methods, or functions. 

PHP 8.2 deprecates the usage of the “${}” syntax. For simple variable expansion, you can convert “${}” to the “{$}” form (e.g., “${foo}” would become “{$foo}”). For cases where you want to use expressions, you can use the following form: 

echo “Hello {${expression}}”

As an example: 

echo “Hello {${$user->getFullName()}}”;

INI Parse Warnings

Many php.ini directives require quantitative values that provide a size (memory usage, file sizes, time intervals, etc.). Prior to PHP 8.2, an incorrect value would be ignored, and the default used. With PHP 8.2, invalid quantitative values will cause a parse warning during startup, notifying administrators that they need to correct the value(s). 

ksort Order Changes

Prior to PHP 8.2, when using ksort() with the SORT_REGULAR flag, keys would be sorted such that alphabetical keys appeared before numerical keys. However, this behavior is different than every other sort function in PHP. As such, starting in PHP 8.2, using ksort() with the SORT_REGULAR flag will now result in numerical keys appearing before alphabetical ones.

str_split changes 

Prior to PHP 8.2, when using str_split() with an empty string, it would return an array containing a single element, an empty string. The behavior was undocumented, and, largely, unexpected by users. As such, starting in PHP 8.2, this scenario will now result in an empty array. 

Back to top

Migrating to PHP 8.2

As noted above, there are a number of backwards incompatible changes that teams will need to watch out for when upgrading or migrating to PHP 8.2. The php.net documentation for PHP 8.2 has a migration guide that is a must read for anyone scoping or performing a migration.

In addition, the PHP ecosystem produces a number of tools that can aid you during such migrations, including: 

  • phpcompat - which is a plugin for PHP  CodeSniffer that provides rules that will flag compatibility issues for you, as well as give some recommendations on how to adapt.
  • Rector - which is a tool that can perform some migrations automatically for you.

Zend also provides PHP migration services to assist your organization in its upgrades. 

Get insights on migrating from PHP 7.4 to PHP 8.2 >>

Back to top

Final Thoughts 

While PHP 8.2 isn’t a game-changing PHP release, it has added some solid quality of life changes. That said, there are some backwards incompatible changes that teams will need to watch out for when they upgrade or migrate to PHP 8.2. 

Improve Critical PHP Applications With ZendPHP + ZendHQ

ZendPHP runtimes, combined with the ZendHQ extension, deliver the building blocks for modern, scalable, and secure web applications. Try both free for 30 days with no strings attached.

Discover ZendPHP  Start Your Trial


Editor's Note: This blog was originally published in 2022, and has since been edited to reflect the PHP 8.2 release date.

Back to top

Additional Resources

Back to top