What's new with PHP 8.2 It's New Features, Changes, Deprecations and Changes
This article will cover what's new in PHP 8.2 with great detail- from its improved features and enhancements to minor deprecations We'll review everything.
As PHP 8.2 entered its feature freezing on July 19 2022, it is likely that there will be nothing new to add to this list.
Excited? We're too.
Let's begin!
The PHP 8.2 release includes new features and improvements. PHP 8.2
We'll begin by looking at every one of the new PHP 8.2 functions. It's a long checklist:
New Read-only
classes
If you declare a class as readonly
, all its properties will automatically inherit the feature of readingonly.
feature. Thus, declaring a class as read-only
is equivalent to declaring every class property as readonly
.
In the case of PHP 8.1 it was necessary to write this code to declare every class's properties as readonly
:
class MyClass
Imagine the same with many more features. Now, with PHP 8.2 it is possible to simply write:
Read-only class MyClassThe class MyClass is read-only.
Additionally, you can declare final or abstract classes to be only read-only
. The order of the keywords does not matter.
abstract readonly class Free {Final read-only class Dom{
You can also declare the class as a read-only
class that has no properties. In effect, it blocks dynamic properties but allows children classes to define their readonly
properties in a clear manner.
Next up, next, read-only
classes can only contain property types that are typed -- this is exactly the same as declaring each of the properties to be read-only properties.
You may make use of this mixed
type property if you are unable to define a property that is strictly typed.
The attempt to define a readonly
class with no specified property type will lead to a Fatal error:
Read-only type $nope public;
fatal error: Readonly property Type::$nope must contain the word "type ... in the line ...
Additionally, you can't declare readonly
for certain PHP attributes:
- Traits
- Interfaces
Attempting to declare any of these options as readonly
can result in a Parse error.
interface with read-only capabilities Destiny{ Parse error: syntax error, unanticipated token "interface" Expecting "abstract" or "final" instead of "readonly" and "class" within ... at page ...
Like every PHP keywords The readonly
keyword does not care about case.
PHP 8.2 also prohibits dynamic properties (more on that later). You cannot stop static properties from being integrated into classes. But, adding dynamic properties to an read-only
class could produce a fatal error.
Error: readonly property Test must have type in ... at the line ...
Allow true
, false
as well as null
as Standalone Types
If you attempted to declare the types as false
or empty
or standalone types -- without the fact that they were in a type union this could result in fatal errors.
function spam(){: null eggs from a function(){: false
Fatal error: Null may not be used in a standalone type in ... at the line ... Error: false cannot not be used to create a stand-alone type within ... in line ...
To stop this happening To avoid this scenario, to avoid this scenario, PHP 8.2 adds support for making use of the false
as well as non-null
as standalone types. By adding this feature, PHP's system of types is now more expressive and complete. You can now specify the return, parameter as well as property types in a precise manner.
Also, PHP still doesn't include an true
type, which appears to be a natural resemblance of the false
type. PHP 8.2 corrects this and adds assistance for the authentic
type as well. It doesn't allow coercion, just like it behaves. fake
type works.
The true
and False
types are basically the same type that PHP uses as a type bool
type. In order to avoid redundancy, you cannot declare these three types together in an unison type. This will lead to the fatality of compile-time.
Disjunctive Normal Form (DNF) Types
Disjunctive Normal Form (DNF) is a standardized way of organizing Boolean expressions. It's a combination of conjunctions which is a boolean term it's an OR of ands.
The RFC offers the following illustration. It assumes the following terms for interfaces and classes are in use:
interface A{ interface B{ C {extends A expands the A interface D{ class W implements the A{
class X implements B{ class Y , which implements A. B{ class Z expands Y and implements C{ .
Through DNF types, you are able to perform type declarations for parameters, properties, and return values , such as:
// Accepts an item which implements A and B// or an object that implements D
(A&B)(A&B)D
// Will accept any object that implements C,
// or is it is a child of X that also incorporates D,
// or nullC// (X&D)null
// Allows any object that implements the three elements of A B, D,
// or an integer, or null. (A&B&D)|int|null
In some instances, the properties may not appear present in DNF forms. Making them DNF could produce an error in parsing. However, you are able to rewrite the words as follows:
A&(B|D)
// Rewriteable by (A&B)|(A&D)
A|(B&(D W))
// Could be rewritten as A(B&D)(B&W)null
You should note that each segment of a DNF type must be unique. For instance the declaration (A&B)(A&B)(B&A)
is invalid as both ORed segments are logically the same.
Adding to this to this, segments that are strictly subsets of the other segment can't be used. This is because the superset will already be able to contain every instance of the subset. Therefore, the use of DNF.
Redact Sensitive Parameters in Traces that are back Traces
A stack trace won't stop the execution of the program. The majority of stack trace operate in the background and are then recorded in a silent mannerto be later inspected if necessary.
The HTML0 RFC proposal provides an illustration:
The most of the most common "offender" is PDO that takes the database password to be a parameter of the constructor and immediately attempts to connect the database inside the constructor instead of using a simple constructor with an separate ->connect() method. Thus when the database connection is unsuccessful, the trace of the stack will contain the password of the database:
PDOException: SQLSTATE[HY000] [2002] No such file or directory in /var/www/html/test.php:3
Stack trace: #0 /var/www/html/test.php(3): PDO->__construct('mysql:host=loca...', 'root', 'password')
#1 main
PHP 8.2 allows you to mark such sensitive parameters with the brand new sensitive parameter
attribute. A parameter with a sensitive label will not be listed within your backtraces. This means that you are able to use them in conjunction with any third-party service.
Here's an easy example that uses one sensitive parameter
When you generate a backtrace, any parameter with the \SensitiveParameter
attribute will be replaced with a \SensitiveParameterValue
object, and its real value will never be stored in the trace. The SensitiveParameterValue
object encapsulates the actual parameter value -- if you need it for any reason.
New mysqli_execute_query
Function and mysqli::execute_query
Method
Have you ever utilized your mysqli_query()
function with potentially escaping user data to run the parameterized MySQLi query?
PHP 8.2 makes running parameterized MySQLi queries easier with the new mysqli_execute_query($sql, $params)
function and mysqli::execute_query
method.
Essentially, this new function is a combination of mysqli_prepare()
, mysqli_execute()
, and mysqli_stmt_get_result()
functions. With it, the MySQLi query will be made ready and connected (if you pass any parameters), and executed within the program. If the query is successful, it'll return a mysqli_result
object. If unsuccessful, it'll return the value of false.
.
The RFC proposal gives a simple and powerful example
foreach ($db->execute_query('SELECT * FROM user WHERE name LIKE ? and type_id (? ? ) (', [$name] $type1 and $type2) as $row)
print_r($row);
Fetch an enum
Properties in const
Expressions
The main reason for the new functionality is the fact that it's not possible to make use of enum
objects in some places such as array keys. In this case, you'll have to use the same value as the the enum
instance to be able to utilize the feature.
Allowing fetching of the enum
properties to places that the enum
objects aren't permitted can make this process easier.
It means the following code is valid now:
Const C = self::B->value =self::B]
And just to be safe To be safe, this RFC also includes support for nullsafe operators ?->
.
Accept Constants in Traits
PHP offers a means to reuse code , referred to as Traits. These are excellent for reuse of code across classes.
In the moment, Traits are limited to defining methods and properties, but not constants. This means that you can't determine the invariants required from a Trait in the Trait's itself. To get around this limitation You must define constants in its composing class or an interface that is implemented by its composing class.
RFC proposes to allow defining constants within Traits. These constants can be defined in the same way as you would define class constants. The following example directly from the RFC will clarify the confusion around its usage:
trait Foo$flags & self::FLAG_3
Constants for Traits are also integrated into the composing definition of the class, which is similar to Traits' method and property definitions. They are also subject to the same restrictions as properties of Traits. As noted in the RFC the proposalalthough a great beginning, needs more development to fully define the feature.
Deprecations in PHP 8.2
Now we can look at all the changes made of PHP 8.2. This list isn't quite large as it is with its latest enhancements:
Do you want to know what we did to increase our visitors by 1000 per cent?
Join 20,000+ others who get our weekly newsletter with insider WordPress tricks!
Deprecate Dynamic Properties (and New #[AllowDynamicProperties]
Attribute)
class Post public int $pid;post = new Post();the name of $post is ''.
Here, you can see that the class Post
class doesn't declare an named
property. But because PHP has dynamic properties, it is possible to define it in a different way than the declaration for the class. It's the most significant advantage, and perhaps the sole -- benefit.
Dynamic properties allow unexpected bugs and behavior to appear within the code you write. If, for instance, you commit a mistake when declaring a property of a class outside of the class, it's very easy to lose track of it -particularly when trying to debug any mistakes within the class.
Beginning with PHP 8.2 and onwards, dynamic properties are removed. The setting of a value for an unregistered class property will trigger a deprecation notice at the time that the property is set. class Foo {> $foo = new Foo; // Deprecated: The dynamic property created by Foo: $bar is no longer supported.$foo->bar = 1; // No deprecation warning The dynamic property is already in existence. $foo->bar = 2;
In addition, as of PHP 9.0 and onwards using the same setting will throw the ErrorException
error.
If your code is full of dynamic properties -- and there's a lot of PHP code that is -- and if you want to stop these deprecation notices after upgrading to PHP 8.2, you can use PHP 8.2's new #[AllowDynamicProperties]
attribute to allow dynamic properties on classes.
#[AllowDynamicProperties]
class Pets
class Cats extends Pets
// You'll get no deprecation warning
$obj = new Pets;
$obj->test = 1;
// You'll get no deprecation warning for child classes
$obj = new Cats;
$obj->test = 1;
As per the RFC, classes marked as #[AllowDynamicProperties]
, as well as their child classes, can continue using dynamic properties without deprecation or removal.
You should also note that, in PHP 8.2, the only bundled class marked as #[AllowDynamicProperties]
is stdClass
. In addition, any properties that can be accessed through __get()
or __set()
PHP magic methods aren't considered to be dynamic properties, so that they don't trigger an error message about deprecation.
Discontinue Partially Supported Callables
Another PHP 8.2 change, albeit that has a lesser impact, is to remove callables that are not supported in part.
The callables listed above are classified as partially supported because you cannot connect directly to them using $callable()
. You can only get to them with the call_user_func($callable)
function. The list of such callables are not very long.
"self::method"
"parent::method"
"static::method"
["self", "method"]
["parent", "method"]
["static", "method"]
["Foo", "Bar::method"]
[new Foo, "Bar::method"]
From PHP 8.2 onwards, any attempts to invoke such functions -- like through the call_user_func()
or array_map()
functions -- - will result in an error message that indicates the function is not supported.
The original RFC gives solid reasoning behind this decision:
In addition to the two previous cases, all of these calls are dependent on context. The technique used to determine what "self::method"
refers to is dependent on the class the call or callability check is performed from. In practice, this usually is true for the final two cases, when used in the form of [new Foo, "parent::method"].
Reducing the context-dependence of callables is the second objective in this RFC. In the wake of this RFC, the only scope-dependence still left is method visibility:"Foo::bar"
might be visible within the scope of one, but not in the other. If callables were to be limited to public methods in the future (while private methods would have to use first-class callables orClosure::fromCallable()
to be made scope-independent), then the callable type would become well-defined and could be used as a property type. But, any changes to visibility handling are not included in this RFC.
As per the original RFC, the is_callable()
function and the callable
type will continue to accept the callables in these types as an exception. However, only when the support is eliminated completely from PHP 9.0 from now on.
To prevent confusion, the deprecation notice's scope has been increased by a brand updated RFC -- which is now inclusive of these exclusions.
It's good to see PHP becoming more oriented towards having a well-defined callable
type.
It is not recommended to use #utf8_encode()
and decode utf8()
Functions
Built-in PHP function utf8_encode()
and decode_utf8()
convert strings encoded with ISO-8859-1 ("Latin 1") to and from UTF-8.
However, their names suggest that they are more widely used than their implementation allows. "Latin 1" is a common encoding "Latin 1" encoding is commonly mistaken for other encodings, such as"Windows Code Page 1252. "Windows Code Page 1252."
In addition, you'll often see Mojibake in situations where these functions cannot convert the correct string. There are no warning messages for errors makes it difficult to spot these functions, particularly in an otherwise clear text.
The PHP 8.2 deprecates both #utf8_encode()
and the utf8_decode()
functions. If you use the functions, you'll be greeted with these deprecation notices:
Deprecated: Function utf8_encode() is no longer supported.Deprecated The function utf8_decode() is no longer in use.
Deprecate $
String Interpolation
PHP allows embedding variables in strings using double quotes ( "
) and heredoc ( ) using a variety of ways:
- Directly embedding variables
"$foo"
- Braces that are outside of the variable --
"$foo"
- Braces following the dollar sign --
"$foo"
- Variable variables --
"$expr"
-- equivalent to using(string) $expr
The three methods listed above are both advantages and disadvantages, while the latter two have complex and contradicting syntax. PHP 8.2 deprecates the last two ways of string interpolation.
Avoid the interpolation of strings by this method in the future:
"Hello, $world! " •Deprecated: {Using $Utilizing $ within strings is not recommended"Hello Hello, $(world)! " •Deprecated: {Using $using $(variable variables) in strings is not recommended.
Beginning with PHP 9.0 These deprecations are upgraded so that they produce an error message.
Deprecate mbstring Functions for Base64/QPrint/Uuencode/HTML Entities
The mbstring (multi-byte string) functions allow us to work with Unicode, HTML entities, and various other text encodings that are older.
But, Base64, Uuencode, as well as QPrint, aren't text encoders which are nonetheless a part of these functions mostly because of the reasons for legacy. PHP is also a separate implementation of these encryptions.
For HTML-based entities PHP has built-in functions such as htmlspecialchars()
and HTMLentities()
-- to deal with these better. For example, unlike with Mbstring, these functions also convert to
. >
and and
characters into HTML entities.
So, keeping all the above to mind PHP 8.2 has been discontinuing the use of mbstring for these encoders (the labels are case-sensitive):
- BASE64
- UUENCODE
- HTML-ENTITIES
- HTML (alias for HTML-ENTITIES)
- Quoted-Printable
- qprint (alias for Quoted-Printable)
Beginning with PHP 8.2 from then on, using mbstring to encode/decode all of these options will emit a deprecation notice. PHP 9.0 will remove mbstring support for these encoders entirely.
Other minor changes in PHP 8.2
We can also look at the PHP 8.2's minor changes, including the removal of features and functions.
Get rid of support for libmysql mysqli
As of now, PHP allows both mysqli
as well as PDO_mysql
drivers to work with mysqlnd
and mysql and libmysql
libraries. However, the preferred and default driver for PHP since PHP 5.4 is mysqlnd
.
Both drivers come with a variety of advantages and disadvantages. But, eliminating the support for any of them -- ideally, removing libmysql
because isn't the standard -can make PHP's code simpler and easier to write unit tests.
In order to justify this benefit To support mysqlnd, the RFC provides a number of benefits from mysqlnd
:
- It's integrated with PHP
- Provides quality-of-life functions (e.g.
get_result()
) - Numeric values returned by with the help of PHP native types
- The functionality of the library does not depend on any external library.
- Optional plugin functions
- Supports asynchronous queries
The RFC also lists some benefits of the libmysql database
that include:
- It is possible to auto-reconnect (
mysqlnd
doesn't allow this feature intentionally, as it is easily exploited) - LDAP and SASL authentication methods (
mysqlnd
may add this feature soon too)
Furthermore, the RFC mentions a number of drawbacks with the libmysql database
-- incompatibility with PHP memory model, many failures in tests, leaks of memory as well as different functionalities among versions, etc.
In light of this, PHP 8.2 removed support for building mysqli
against mysql's libmysql
.
If you'd like to add the functionality only accessible with the libmysql library
it's necessary to explicitly add it to mysqlnd
as a feature request. Also, you cannot add auto-reconnect.
Locale-Independent Case Conversion
For instance, if you selected "Turkish" as well as "Kazakh" languages when you installed Linux and you'll see that you can use toupper('i')
to obtain its equivalent in uppercase will result in the dotted capital I (U+0130, I
).
PHP 8.0 stopped this anomaly by changing the default locale to "C," unless the user makes a specific change through setlocale()
.
PHP 8.2 goes even further by eliminating the sensitivity to locales from the case conversions. The RFC primarily changes strtolower()
, strtoupper()
, and related functions. Read the RFC for a list of all the affected functions.
As an alternative, if you'd like to implement localized case conversion you may utilize mb_strtolower()
.
Random Extension Improvement
PHP plans to change its random functions.
As of now PHP's random function is heavily dependent upon the Mersenne Twister state. But, the state is stored implicitly in PHP's global location- there's no way a user can access it. The addition of randomization features between the first seeding stage as well as the intended usage would break the code.
Maintaining such code can be much more difficult when your code uses external packages.
Therefore, PHP's present random functionality cannot reproduce random values in a consistent manner. Even, it fails test of statistical consistency for random number generators, like TestU01's Crush as well as BigCrush. Mersenne Twister's 32-bit limitation further exacerbates this.
So, using PHP's built-in functions -- shuffle()
, str_shuffle()
, array_rand()
-- isn't recommended when you want to secure cryptographic random numbers. In such cases it is necessary to create a new function that uses the random_int()
or similar functions.
But, several issues with the RFC came up following the voting had begun. This setback forced the PHP team to document all the issues in an independent RFC that included a vote choice for each issue. They'll decide on moving further until they reach an agreement.
Additional RFCs for PHP 8.2
PHP 8.2 is also packed with many new features and small changes. Below, we'll discuss them with hyperlinks to other information:
- New
curl_upkeep
function: PHP 8.2 adds this function to its Curl extension. The function calls thecurl_easy_upkeep()
function in libcurl, the underlying C library which uses by the PHP Curl extension uses. - New
memory_reset_peak_usage
function: This function resets the peak memory usage returned by thememory_get_peak_usage
function. It can be handy for when you're performing the same action multiple times and need to keep track of every run's maximum memory consumption. - Support for no-capture mod (
/n
) inpreg_*
functions: In regex, using the()
metacharacters indicate a capturing group. That means all matches for the expression within the bracket are returned. PHP 8.2 introduces a no-capture modifier (/n
) to prevent this behaviour. - Allow iterator_*() family accept all
iterator_*()
family accept all iterables as of today the PHPiterator_*()
family only accepts\Traversables
(i.e. no plain arrays allowed). This restriction is unnecessary the possibilities, and this RFC fixes the issue.
Summary
PHP 8.2 builds upon the huge improvements made in PHP 8.0 as well as PHP 8.1, which is not an easy task. Our top picks for the most thrilling PHP 8.2 highlights are the novel standalone types, read-only properties, as well as a myriad of performance improvements.
Be sure to save this blog post for your next information.
What PHP 8.2 features you like the most? Which of the deprecations you find least preferred? Do share your views on our forum in the remarks!
Save time, costs and increase site performance:
- Help is available immediately 24/7 support from WordPress hosting experts, 24/7.
- Cloudflare Enterprise integration.
- Reaching a global audience with 34 data centers around the world.
- Optimization using our integrated Application Performance Monitoring.