decorative image for blog regarding PHP 8.2
March 29, 2023

Key Features and Changes in PHP 8.2

PHP Development
Modernization

With PHP 8.2 now available, PHP teams around the world are considering when, or if, they will upgrade to this latest PHP version

In this blog, we discuss the PHP 8.2 release, including the key features, improvements, and deprecations teams can expect. 

Back to top

PHP 8.2 Release Date

PHP 8.2 was released 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 Release Date 

PHP 8.2 was released on December 8, 2022. 

PHP 8.2 Support Lifecycle 

PHP 8.2 will be supported until December 8, 2025 -- which is 3 years from the day of release, with active support until December 8 2024, and security support until December 8 2025. After that point, PHP 8.2 will be end of life and not receive any new patches. 

Branch

GA Release

Active Support (Community)

Security Support (Community)

PHP 8.2

December 8, 2022

December 8, 2024

December 8, 2025

Back to top

What to Expect in PHP 8.2

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.

Notable Features 

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

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 

Notable 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 

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)” 

${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. 

Need LTS or Migration Services for Your PHP?

Zend can help. Learn more about our LTS options and migration services via the links below. 

See LTS Options  See Migration Services

Keep Reading >> PHP Trends to Watch in 2023

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

Back to top