PHP 8.3: Let’s discuss the new features!
The PHP project publishes a new major or minor version of PHP at the end of each year. The authors announce a feature freeze around six months before the release; in the meantime, there's a flurry of activity as developers lobby for adoption of language modifications with every new release.
PHP 8.3 is releasing its new features on November 23 of this year. Like every time, they have included some amazing additions this time as well. Along with that, they are repudiating some of the vestiges from previous versions too.
We have compiled all that you need to know about these features in this article. So, read along!
Table Of Contents:-
- PHP 8.3 New Additions:
- Typed Class Constants
- json_validate() function
- Dynamic class constant and Enum number fetch support
- gc_status() now returns additional information
- New \Random\Randomizer::getBytesFromString method
- New \Random\Randomizer::getFloat() and nextFloat() methods
- Fallback value support for PHP INI Environment Variable syntax
- PHP CLI Lint supports linting multiple files at once
- class_alias() supports aliasing built-in PHP classes
- New stream_context_set_options function
- PHP 8.3 Deprecations and Changes:
PHP 8.3 New Additions
Let’s look at the new additions that have come in this year,
1. Typed class constants
PHP 8.3 introduces a new type declaration for class constants. This ensures type compatibility when child classes and interface implementations override them. From now, you can declare the type after const
keyword.
class Test {
const string TEST_CONSTANT = 'test';
}
Class constants support standard PHP standalone types, nullable types, union types, intersection types, and DNF types. But the following declarations are not allowed and tehy would return fatal error.
class Test {
const void FOO = 'test';
const never FOO = 'test';
const callable FOO = 'test';
}
Fatal error: Class constant Test::FOO cannot have type void
Fatal error: Class constant Test::FOO cannot have type never
Fatal error: Class constant Test::FOO cannot have type callable
Further, you must remember that is a parent class declares a constant type, all the subclasses within it also must declare the same type .i.e., they cannot work without declaring any type.
class ParentClass {
public const VALUE = 'MyValue';
}
class ChildClass extends ParentClass {
public const VALUE = 'MyValue';
}
Fatal error: Type of ChildClass::VALUE must be compatible with ParentClass::VALUE of type string|int
2. json_validate() function
Prior to PHP 8.3, the only way to determine if a given string is a valid JSON string was to attempt to decode it, and see if any errors were emitted. The new json_validate
function uses the same underlying JSON parser PHP uses, but consumes less memory and processing as json_decode
only analyzes the string without constructing any decoded value.
But in the new update they have included the json_validate
function, which returns a true or false value w.r.t. User input json strings.
json_validate('[1, 2, 3]'); // true
json_validate('{1, 2, 3]'); // false
Example of json_validate
in action:
<?php
$jsonData = '{"name": "John", "age": 30, "email": "john@example.com"}';
$jsonSchema = '{"type": "object", "properties": {"name": {"type": "string"}, "age": {"type": "integer"}, "email": {"type": "string", "format": "email"}}}';
if (json_validate($jsonData, $jsonSchema)) {
echo "JSON data is valid!";
} else {
echo "JSON data is invalid.";
}
This function simplifies the validation process, reducing the complexity and potential errors associated with custom validation routines.
3. Dynamic class constant and Enum number fetch support
Earlier, you could not access class constants and enum numbers in PHP 3.8, but now you can use a variable name to do so.
class MyClass {
public const MY_CONST = 42;
}
$constName = 'MY_CONST';
- echo \constant("MyClass::$constName");
+ echo MyClass::{$constName};
Similarly, for enum,
enum MyEnum: int {
case MyMember = 42;
}
$enumName = 'MyMember';
- echo \constant("MyEnum::$enumName")->value;
+ echo MyEnum::{$enumName}->value;
The expression inside the {} is not limited to a variable name. Any expression that returns a string is allowed.
4. gc_status() now returns additional information
gc_status
or garbage collector status in PHP returns statistics for running status, protection and buffer size. gc_status
is usually required to optimize memory usage.
$gcStatus = gc_status();
echo "Total collected cycles: " . $gcStatus['cycles'];
echo "Memory usage before collection: " . $gcStatus['memoryUsageBefore'];
echo "Memory usage after collection: " . $gcStatus['memoryUsageAfter'];
As of now, when we run gc_status
, it returns an array with four keys, but in the updated 8.3 version, eights keys are returned.
Field | Type | Description |
---|---|---|
Running | Boolean | True, if the garbage collector is running; False, otherwise. |
Protected | Boolean | True, if the garbage collector is protected and root additions are forbidden; False, otherwise. |
Full | Boolean | True, if the garbage collector buffer size exceeds GC_MAX_BUF_SIZE. This is currently set to 1024^3 |
buffer_time | Integer | Current garbage collector buffer size. |
application_time | Float | Total application time in seconds, including collector_time |
collector_time | Float | Time spent collecting cycles in seconds (includes destructor_time and free_time) |
destructor_time | Float | Time spent executing destructors during cycle collection, in seconds |
free_time | Float | Time spent freeing values during cycle collection, in seconds. |
5. New \Random\Randomizer::getBytesFromString method
The \Random\Randomizer
class in PHP 8.3 supports a new getBytesFromString
method that returns a random number sequence of a requested length ($length parameter), only containing a bytes from the requested series of bytes ($string parameter).This method allows developers to obtain secure random bytes from a given string, providing a versatile and customizable approach to random data generation.
$rng = new Random\Randomizer();
$chars = 'AEIOU';
$rng->getBytesFromString($chars, 1); // "E"
$rng->getBytesFromString($chars, 5); // "AIIEO"
$rng->getBytesFromString($chars, 10); // "IEAUAIIOUE"
Note that the \Random\Randomizer::getBytesFromString()
method works on the byte level. It cannot effectively shuffle multi-byte characters such as Emojis, CJK characters, and Eastern/Indo characters.
These methods allow developers to obtain high-precision random floating-point numbers within a specified range, enhancing the accuracy of random data.
6. New \Random\Randomizer::getFloat() and nextFloat() methods
Using \Random\Randomizer::getFloat()
involves providing a minimum and maximum value, and the method generates a random floating-point number within that range.
Example: Generate a random number in the range 0 <= and < 1:
$rng = new Random\Randomizer();
$rng->nextFloat(); // 0.21185336351144
7. Fallback value support for PHP INI Environment Variable syntax
In PHP 8.3, PHP INI values can be substituted with feedback values if any particular environment variable is not set for it.
session.name = ${SESSION_NAME:-Foo}
sendmail_from = "${MAIL_FROM_USER:-info}@${MAIL_FROM_DOMAIN:-example.com}"
ini_get('session.name');
ini_get('sendmail_from');
the session.name value will be the value of the SESSION_NAME
Environment variable if it is set, but it now uses Foo value otherwise.
sendmail_from
value will also fall back to info@example.com
if both MAIL_FROM_USER
and MAIL_FROM_DOMAIN
Environment variables are not set. If either of them are available, the Environment variable will be used.
8. PHP CLI Lint supports linting multiple files at once
PHP’s CLI allows linting to check a file name for syntax errors before executing. But the problem was that you could not lint multiple files together. How many ever files you passed, CLI linted only the first PHP file. This problem is sorted out in the new feature. Now, you can lint all the files in a single invocation.
- If there is any file that was not accessible, the exit code will be 1.
- If any of the files failed to lint, the exit code will be 255.
- When both errors conditions are present, the exit code will be 1.
9. class_alias() supports aliasing built-in PHP classes
In PHP 8.3, the class_alias()
function gains the ability to alias built-in PHP classes, which was not possible before. Using class_alias()
to alias a built-in PHP class involves specifying the desired alias and the original class name as arguments. Once aliased, the original class can be referenced by its alias throughout the codebase.
class_alias(\DateTime::class, 'MyDateTime');
$customDateTime = new MyDateTime();
10. New stream_context_set_options function
PHP < 8.3 had a stream_context_set_option
function which is used to support function signatures. It can either accept an array of options to set for one or more contexts or wrappers, or it can accept a single wrapper name, option name, or its value.
function stream_context_set_option($stream_or_context, string $wrapper, string $option, mixed $value): bool {
// Function body (if any)
}
function stream_context_set_option($stream_or_context, array $options): bool {
// Function body (if any)
}
Now, they have made a new stream_context_set_options
function (option changed to options), which will support the second signature function.
There is news that the first signature function will be deprecated in PHP 8.4 an further the earlier stream_context_set_option
will be entirely removed in PHP 9.0.
PHP 8.3 Deprecations and Changes
1. get_class() and get_parent_class() changes
Like how you saw in the last paragraph, PHP is on a spree deprecating all those functions which were using more than one signature. get_class
and get_parent_class
functions accept an object $object
parameter that returns the name of the class, or the name of the parent class. However, it also supports an alternative signature that, when no parameters are passed, it returns the name of the class in context.
class MyException extends InvalidArgumentException {
public function __construct() {
get_class(); // "MyException"
get_parent_class(); // "InvalidArgumentException"
}
}
In PHP 8.3, calling get_class
and get_parent_class
functions without parameters is deprecated. In PHP 9.0 the functionality allowing for the existence of multiple versions of a function with differing parameters will be eliminated. This means that if you don’t provide the $object parameter, you will get an error called ArgumentCountError.
2. unserialize(): E-NOTICE to E- WARNING
PHP provides serialize and unserialize function to serialize any PHP values to string and vice-versa. Previously, passing an invalid string to the unserialize()
function emitted PHP notices (E_NOTICE) in certain cases, such as syntax errors. Since PHP 8.3, warnings (E_WARNING) are emitted instead. Moreover, certain error conditions of the serialize()
function now emit E_WARNING. These include:
- Syntax errors
- Failures in the custom unserialize handlers using
__unserialize
magic method; e.g the__unserialize()
method not returning any value
class Test {
public function __unserialize(array $data) { } // Does not return anything
}
3. Returning the same variable twice from __sleep()
magic method causing a name clash
class Test {
public $foo = 'test';
public function __sleep() {
return array("foo", "foo"); // Same value returned twice
}
}
serialize(new Test());
3. HTML Highlight tag changes
Syntax highlighting is supported by PHP's highlight_file
and highlight_string
functions. A file or string containing PHP code is accepted, and an HTML snippet containing PHP keywords, functions, and other tokens is returned. PHP INI directives control the colors of the syntax highlighter.
PHP 8.3 makes some changes to the syntax highlighter, resulting in changes to the resulting HTML output.
Additionally,
- Output is now wrapped in
<pre><code></code></pre>
- Line-breaks no longer converted to
<br />
tags - White spaces and tabs are no longer converted to HTML entities
<?php
function hello(): void {
echo "Hello World";
}
hello();
echo highlight_string(string: $code, return: true);
How it comes on PHP < 8.3:
<code>
<span style="color: #000000">
<span style="color: #0000BB"><?php<br /></span>
<span style="color: #007700">function </span>
<span style="color: #0000BB">hello</span>
<span style="color: #007700">(): </span>
<span style="color: #0000BB">void </span>
<span style="color: #007700">{<br /> echo </span>
<span style="color: #DD0000">"Hello World"</span>
<span style="color: #007700">;<br />}<br /><br /></span>
<span style="color: #0000BB">hello</span>
<span style="color: #007700">();</span>
</span>
</code>
How it comes in PHP 8.3:
<pre><code style="color: #000000">
<span style="color: #0000BB"><?php</span>
<span style="color: #007700">function </span><span style="color: #0000BB">hello</span><span style="color: #007700">(): </span><span style="color: #0000BB">void </span><span style="color: #007700">{</span>
+ echo <span style="color: #DD0000">"Hello World"</span><span style="color: #007700">;</span>
+ }
+
+ </span><span style="color: #0000BB">hello</span><span style="color: #007700">();</span>
</code></pre>
4. Granular DateTime Exceptions
To better convey error and exception states, PHP 8.3 introduces extension-specific and granular Exception and Error classes. This makes it easier and cleaner to catch date-specific exceptions.
The new exception or error classes are added on top of existing \exception and \error classes and hence if your program already catches these errors, it will additionally catch any of these new errors as well.
Conclusion
In general, the PHP 8.3 version does not have any significant additions as compared to PHP 8.1 and 8.2.
This version has mostly concentrated on improving the language and aligning some features with how the language has evolved in the past several years. However, there are some tempting upgrades for developers and teams who know how to use them wisely.
With that said, if you have any queries about shifting to PHP 8.3, I would suggest you to go through the documentation carefully.
Atatus: PHP Performance Monitoring and Error Tracking
With Atatus, you can effectively monitor your PHP Application, providing a comprehensive view of transaction performance, tracking errors and exceptions, identifying slow database queries, monitoring delayed external requests, and offering function-level traces to pinpoint performance bottlenecks, among other features.
Atatus PHP monitoring, tracks and provides real-time notifications for every error, exception, and performance problem that occurs within the application. .
By tracking KPIs such as response times, throughput, HTTP failure rates, and error rates, it can help users identify and address any performance issues before they impact the application's users.
Furthermore, Atatus supports multiple PHP framework such as WordPress, Magento, Laravel, CodeIgniter, CakePHP, Symfony, Yii and Slim making it an adaptable tool that can be used to monitor applications across different frameworks and platforms.