PHP 8.3 Release: Exciting Updates that You Should Know About

Table of Contents

PHP 8.3 is here, and PHP developers worldwide are eager to get their hands on this latest release. PHP 8.3 is the latest release (after 8.2.12) of the PHP framework, bringing forth a suite of new features, changes, and deprecations that will revolutionize the web development approach, especially backend development. It has been tested through alpha releases, passed the feature freeze stage, and again tested through three betas and six release candidates (RC). This article will detail the latest features and changes to help you remain updated in modern programming.

New Features in PHP 8.3

In this section, we will explore all the new features of PHP 8.3 and how they will help PHP developers in the long run.

Typed Component Classes

PHP 8.3 has made significant enhancements to help dedicated PHP developers handle class components more efficiently. The release has introduced typed class components as a part of this enhancement. Let us understand it in detail.

  • Type declaration for Class Components: PHP 8.3 will allow developers to declare types for class components. Simply put, after the declaration of a constant in a class, you can specify the type of value the constant will hold. Furthermore, type declaration enforces the rule of adhering to the declared type when any interface or subclass overrides a constant. This can help when you handle class hierarchies that involve interfaces and subclasses. For example, when a parent class declares a constant as an integer, the subclass overriding it must also use an integer type. PHP 8.2 and previous versions enforcing type compatibility led to inconsistencies and potential bugs in the code. Therefore, PHP 8.3 promotes the usage of consistent constants throughout the class hierarchy for a robust codebase.
  • Syntax and Usage: Place the desired type right after the “const” keyword within the class to declare a typed constant. For example, to declare a constant as an integer, you must write “const string TEST_CONSTANT = ‘test’;”
  • Used Across Different Class Components: Typed class components can be used across various class components. They can be declared within classes with different visibility levels like public, protected, and final protected. Furthermore, these components can be declared within traits to reuse constant definitions across various classes. They can also be used in interfaces for robust constant definitions between classes and the interface. Moreover, they can also be used in Emus to structurally define a set of possible values that adhere to a specific type.
  • Supported and Unsupported Types: Class components support DNF, intersection, nullable, standard PHP, and union types. However, class component types do not support void and never types used as return types and callable, which is context-dependent.
  • Strict Typing Behavior: Typed class constants undergo strict evaluations regardless of the declaration of strict_types in the PHP script.
  • Variance: Class constant types follow the Liskov Substitution Principle (LSP). Thereby, they can be narrowed or kept the same in implementations/subclasses like return types. However, PHP emits a fatal error during compilation when a class component attempts to change or widen the declaration.
  • Omitting Constant Type Declarations: All subclasses must declare compatible constant types when a parent class declares a constant type. When you omit the class component type, PHP considers it incompatible and results in error.
  • Reflection API Support: Reflection API provides two methods to retrieve the type of class components in PHP 8.3 – the hasType() method and the getType() method. The hasType() method lets you know if the constant is declared with a constant. The getType() method returns ‘null’ on the declaration of a class component with no type or a ReflectionType object on the declaration of a type.
  • Backward Compatibility Impact: Your code will not compile and result in a parse error in PHP 8.2 and earlier versions if it uses typed class components.
json_validate Function

PHP 8.3 also introduced the json_validate function for improved JSON handling capabilities, leading to a great web app development experience. Let us explore the key features of this new addition:

  • Purpose: The json_validate function returns “true” or “false” after determining whether a given string is a validated JSON string or not. You can simply use json_validate($_GET[‘json’]) for the same. Earlier, to ensure a valid JSON string, you needed to decode it and check for errors. The json_validate function uses the same JSON parser as PHP, yet it consumes less memory and processing.
  • Usage: You can throw an exception for invalid JSON using json_validate with json_last_error_msg and json_last_error. Furthermore, you can replace json_decode-based validation techniques with json_validate to remove unnecessary decoding and optimize performance.
  • Signature: The json_validate function is declared in the global namespace as json_validate(string $json, int $depth = 512, int $flags = 0): bool. It validates a string for JSON compliance.
  • Accepted Flags ($flags): For its third parameter, ‘$flags’, the json_validate function accepts the bit-mask of flags. Currently, the function only accepts the JSON_INVALID_UTF8_IGNORE flag for the ‘$flags’ parameter. This flag instructs json_validate and json_decode to ignore UTF-8 characters in the provided string.
  • Error Handling and Validation: When json_validate does not return validation error codes, you can use json_last_error and json_last_error_msg to determine it.
  • Backward Compatibility: You may face a redeclaration error when updating your PHP application in the 8.3 version if it has a json_validate function in the global namespace.

Dynamic Class Constant and Enum Member Fetch Support

PHP 8.3 allows you to use a variable name to fetch class constants and Enum objects. For example, echo MyClass::{$constName}; will fetch the constant using the $constName variable. Furthermore, you can use echo MyEnum::{$enumName}->value; to retrieve an Enum member. Moreover, adding a string-returning expression instead of a variable name within {} enhances code flexibility. This feature of PHP 8.3 also supports ::class magic constants. These constants return a class’s/Enum’s fully qualified class name.

In PHP 8.2 and previous versions, you require the constant() function to fetch class constants and Enum members. Furthermore, it often results in syntax errors.

However, when you fetch undefined class components and Enum members, it returns an undefined constant error​. While fetching components and members with a non-string type expression, it returns a TypeError exception. Moreover, this fetch syntax will not work on PHP 8.2 and earlier versions.

gc_status() Function Delivers Additional GC Information

PHP 8.3 improved the gc_status() function with additional fields. Now, the function delivers the following extra data and statistics about the PHP Garbage Collector:

  • Application Time: Returns total application time (including collector time) in seconds.
  • Buffer Full Status: Shows ‘true’ or ‘false’ based on whether the buffer size of the garbage collector exceeds GC_MAX_BUF_SIZE (that is set to 0x40000000 = 1024³).
  • Buffer Size: Displays the current buffer size of the current garbage collector.
  • Collector Time: Returns the time spent collecting cycles (including destructor and free time) in seconds.
  • Free Time: Displays the time taken to free values during cycle collection in seconds.
  • Protection Status: Shows ‘true’ or ‘false’ based on whether the garbage collector is protected or not.
  • Running Status: Returns ‘true’ or ‘false’ based on whether the garbage collector is running or not.

Despite adding these eight fields for comprehensive garbage collector data, the gc_status() function retains its original function signature and return value type. Furthermore, you cannot replicate these internal GC insights in user-land PHP. Therefore, you cannot port these data into older PHP versions.

Random Extension

PHP 8.3 introduced three new methods in the \Random\Randomizer class:

  • getBytesFromString

    The getBytesFromString method uses bytes to return a random number sequence of a specified length from the provided series of bytes. However, this method operates on a byte level and cannot shuffle CJK characters, Eastern/Indo characters, Emojis, and other multi-byte characters. The method handles duplicate characters quite effectively.

    It allows duplicate characters in the $string parameter, which increases the chance of the frequent appearance of these characters in the random sequence. Furthermore, the method throws a \ValueError exception when the $string is empty, and the $length is less than or equal to zero. Furthermore, it throws a \Random\BrokenRandomEngineError exception when the underlying engine fails to generate a random byte sequence as per the requested length.

    This method is newly added to the PHP Random extension in 8.3, and the Randomizer class is finalized. User-land PHP polyfills can use this method for the Random extension’s Randomizer class.

  • getFloat()

    \Random\Randomizer::getFloat() method generates a random float value in a range greater than or equal to 0 or less than 1. This method accepts a \Random\IntervalBoundary Enum as a third parameter to determine whether the $min and $max boundaries should be inclusive or exclusive. Furthermore, this method will not cause any backward compatibility issue until an Enum or user-and \Random\IntervalBoundary class is declared.

  • nextFloat()

    The \Random\Randomizer::nextFloat() method is similar to the getFloat() method. It also produces random float values in the same range. However, unlike getFloat(), nextFloat() is an instance method and, when implemented, can be called a Randomizer object instance. This method also has the same backward compatibility impact as getFloat().

Fallback Value Support

PHP 8.3 will offer fallback value support to effectively handle PHP INI Environment variables. Using the ‘:-’ symbol, you can declare a fallback value to extend the INI Environment variable substitution. The specified fallback value is used when an environment variable is not set. Let’s check out some of the features of this support:

  • Nested Fallback Values: The fallback mechanism allows using environment variables as fallback values. Thereby, it allows nested fallbacks.
  • PHP Constants as Fallbacks: PHP INI values, which can be modified during run-time, can use PHP constants as the fallback value.
  • Type Coercion: PHP coerces fallback values that follow the same rules as standard string literals configuration values. For example, “true” is coerced to “1” and false to an empty string (“”).
  • Security Considerations: This syntax supports PHP constants, and therefore, you should take special care while parsing user-provided INI values. PHP advises using the INI_SCANNER_RAW flag to disable PHP’s constant substitution and environment variable while parsing.
  • Supported Functions: All PHP functions that deal with INI values support this syntax. Some of these functions include get_cfg_var(), ini_get(), ini_get_all(), ini_set(), parse_ini_file(), and parse_ini_string().
  • Version Compatibility: PHP 8.2 and older versions do not support this syntax. However, a user-land INI parser may use the values with the ${FOO:-BAR} syntax to mimic its behavior.
php -l Supports Linting Multiple Files in Single Commands

In PHP 8.2 and older versions, only one file used to be linted despite providing numerous files. PHP 8.3 lets PHP CLI lint multiple files using a single command. The following section explores the functionality of this new feature in detail:

  • Error Display and Continuation: When the linter encounters an error, it displays the error and continues linting the remaining files. The process exits with an error when it fails to lint a file.
  • Exit Codes: If the new syntax cannot access a particular file, it will show the exit code 1. Furthermore, on failure to lint any file, PHP CLI will return 255. When both errors are present, the system will return 1.
  • Glob Pattern Support: In PHP’s earlier versions, glob patterns could only lint the first file in a series. PHP 8.3 allows PHP CLI to use a glob pattern to lint multiple files. Hence, it simplifies limiting complex data structures and large directories.
  • Third-party Tools: Tools like php-parallel-lint/PHP-Parallel-Lint can parallelly lint multiple files across various PHP versions.
Aliasing Built-in PHP Classes using class_alias()

The class_alias function creates aliased classes for any given class that behaves similarly to the original class. In the earlier versions of PHP, developers faced a ValueError exception when aliasing built-in PHP classes. PHP 8.3 correctly aliases internal classes and interfaces using class-alias().

New stream_context_set_options Function

The stream_context_set_option function sets options for a context resource or stream. It supports two function signatures – an array of options (to set for single or multiple contexts/wrappers) or a resource (option name, single wrapper, or its value). PHP aims to deprecate the overload signature of stream_context_set_option() in PHP 8.4 and remove it in PHP 9.0. Therefore, PHP 8.3 introduced the stream_context_set_options function to set an array of options.

In PHP 8.2 and older versions, you can use stream_context_set_option with an array-based signature to implement the stream_context_set_options polyfill. Furthermore, the stream_context_set_options only creates a compatibility issue once a user-land PHP function is declared with the same name.

Changes in PHP 8.3

PHP 8.3 made several changes to its functions, eliminating major PHP vulnerabilities. Let us explore them in detail.

Upgrade of E_NOTICE to E_WARNING in the unserialize() Function

In earlier PHP versions, the unserialize() function returned E_NOTICE when an invalid string was passed. In PHP 8.3, the unserialize() function emitted E_WARNING instead of E_NOTICE. Furthermore, the following error conditions of the unserialize() function also emit E_WARNING:

  • Syntax errors in the passed string (caused by incorrect serialization handlers).
  • When custom unserialize handlers, using __unserialize, fails.
  • The occurrence of a name clash when the same variable is returned twice from the __sleep() magic method.
highlight_file and highlight_string output

PHP 8.3 made three prime changes to the HTML outputs of highlight_file and highlight_string functions:

  • Tag Wrapped Outputs: PHP 8.3 and its later versions wrap the highlight_file and highlight_string output in <pre><code></code></pre> tags. Furthermore, it removes the outermost <span> tag and inserts style=”color: to the <code> tag.
  • Preserving Line Breaks: PHP 8.3 preserves the original code break in the HTML snippet. The functions do not convert the new-line characters (\n) in the highlighted code into HTML <br/> tags.
  • Conversing White Spaces and Tabs: In PHP 8.3, white-space characters are no longer converted to &nbsp; and remain unchanged. Furthermore, the tab characters are converted to four standard space characters instead of HTML entities (&nbsp;&nbsp;&nbsp;&nbsp;).

Yet the function signatures remain unchanged. PHP applications using highlight_file and highlight_string functions may need to update the CSS to accommodate the <pre><code> tags. Furthermore, browsers will render new-line characters as <pre> tag-wrapped new lines. Developers should make CSS adjustments for inline <pre><code> tags within <p> tags.

Granular Date/Time Exceptions

In PHP 8.3, the Date/Time uses extension-specific, granular Exception and Error classes instead of standard \Exception and \Error. This results in clear data errors and exceptions related to date and time operations. Furthermore, the new version has added nine Exception/Error classes to this extension.

User-land PHP codes can throw these exceptions, yet they are conventionally reserved for the Date/Time extension. However, you cannot port the new changes to the older versions, but you can polyfill the classes to the older PHP versions. It can help PHP applications unserialize exception objects thrown or use the new Exception/Error classes in older versions. Now let us explore the hierarchy of the Date/Time extension classes:

DateError

DateError and its subclasses, DateObjectError and DateRangeError, are used for errors related to the Date extension or PHP runtime. They are thrown when the underlying timelib database is corrupted, indicating an issue with the PHP setup.

DateObjectError is thrown for improperly initialized Date/Time class objects. DataRangeError is thrown while processing a date exceeding the PHP integer value.

DateException

DateException is thrown for invalid or malformed user-provided values to the Date/Time classes or functions. DateException has five subclasses:

  1. DateInvalidTimeZoneException: This exception is thrown during two instances. The first is when a PHP developer tries to instantiate a DateTimeZone class object with an undefined timezone name. The second is when you set an out-of-range timezone offset.
  2. DateInvalidOperationException: PHP throws a DateInvalidOperationException exception when you enforce an invalid operation on a DateTime object.
  3. DateMalformedStringException: When the extension fails to parse a valid date/time in the given string, PHP throws the DateMalformedStringException exception.
  4. DateMalformedIntervalStringException: This exception is thrown when the extension classes encounter an invalid string.
  5. DateMalformedPeriodStringException: When developers try instantiating DatePeriod class instances with malformed period strings, it throws DateMalformedPeriodStringException.

Furthermore, certain warnings in PHP 8.2 and earlier versions are turned into exceptions in PHP 8.3. Some warnings that turn into exceptions are DateException, DateInvalidOperationException, and DateMalformedIntervalStringException.

Class Constant Type Declarations

This is a follow-up update of Type Consonants in PHP 8.3. In this update, constant types have been used to upgrade Phar, SNMP, and ZipArchive class constants. When any user-land PHP classes extend any of these classes or override existing constants, it can lead to a fatal error. However, if such an attempt is made, the new declaration must have a class constant type and be compatible.

$_SERVER[‘SERVER_SOFTWARE’] Value Changed for Compliance

PHP’s built-in CGI-compatible server tests PHP applications without using fully-fledged server software. Despite following RFC3875, its $_SERVER[‘SERVER_SOFTWARE’] value violated RFC3875 – 4.1.17. The necessary changes were made through PHP 8.3 to ensure compliance. Currently, PHP’s CLI server follows a pattern that adheres to RFC.

The change will not impact any existing PHP application since the $_SERVER[‘SERVER_SOFTWARE’] value does not appear in any HTTP heading or outputs. However, applications that inspect this value to determine whether the built-in serves it will be affected.

Deprecations in PHP 8.3

This section will delve into all the functions that PHP 8.3 disapproves of and their replacement to ensure compatibility with PHP 8.3 and above versions.

Deprecated get_class() and get_parent_class() Function Calls Without Arguments

PHP 8.3 has deprecated several class and function methods supporting more than one signature. get_class() or get_parent_class() are two such methods. These accept an “object $object” parameter that delivers the class name and, in the case of the get_parent_class function, displays the name of the parent class. Furthermore, it returns the class name in context when no parameters are passed.

PHP 8.3 disapproves calling get_class() or get_parent_class() without any parameters. PHP 9.0 will remove the alternative signature that causes an ArgumentCountError exception when the object $object parameter is not passed.

  • Replacement get_class(): You can only call the get_class() function within a class context in PHP. Furthermore, self::class or __CLASS__ constants can replace the deprecated get_class call. PHP 5.4 and the above versions support the self::class magic constant, while PHP 5.0 and later versions support the __CLASS__ constant. Furthermore, while keeping the get_class call, you can also pass $this to get_class to avoid deprecation calls.
  • Replacement for get_parent_class(): get_parent_class() and parent::class magic constant returns the same value when the former function calls with no parameters. Hence, get_parent_class() calls can be replaced with parent::class magic constant. Passing $this to get_parent_class() works. However, the behavior is different from get_parent_class since using parent during the absence of a parent class results in an error.

Also Read: PHP or Laravel: Which is Better for Web Application Development?

Conclusion

The new features in PHP 8.3 will enhance the web application development approach if you use it correctly. PHP will bring more new features, changes, and deprecations to make its environment better for developers. So, do follow us to learn more about PHP’s upcoming updates.

Share

Recent Awards & Certifications

[class^="wpforms-"]
[class^="wpforms-"]
[class^="wpforms-"]
[class^="wpforms-"]