Features PHP 7.3 Lead image: Lead Image © MIR, Fotolia.com
Lead Image © MIR, Fotolia.com
 

New features in PHP 7.3

Prime Numbers

The new PHP 7.3 simplifies string handling, supports PCRE version 2, adds LDAP controls, improves logging, and deprecates some features, functions, and syntax elements. By Tim Schürmann

PHP version 7.3 [1] became available at the end of 2018. At first glance, the innovations do not appear spectacular, but they could disrupt existing scripts. That said, with deprecations and end of support for older PHP versions, website owners might want to consider switching to the new version as soon as possible.

PHP 7.3 not only throws some ballast overboard, it also introduces syntax changes. In everyday life, programmers may particularly notice the switch to PCRE2 (Perl-compatible regular expressions, version 2), the changed behavior in multibyte string functions, and the more flexible Heredoc and Nowdoc syntax.

The Here and Now

The Heredoc syntax simplifies the assignment and output of longer text by replacing strings in double quotation marks with text between delimiters. For example, if $name = "Hans Hansen";, the Heredoc

$output = <<<EOT
My name is: "$name".
EOT;

would output My name is: Hans Hansen. In a Heredoc, the <<< operator is followed by an identifier that signals the beginning of text. The text continues until the identifier appears again to mark the end of the Heredoc.

Nowdoc syntax was introduced in PHP 5.3.0. It behaves like text in single quotes, which PHP does not interpret. If you change the first line of the example to

$output = <<<'EOT'

$output would display the text My name is: "$name".

In older PHP versions, a semicolon and a blank line always followed the second identifier at the end of the string. The expression EOT; echo $output; was not allowed, for example. In PHP 7.3, this constraint has been eliminated for both Heredoc and Nowdoc. Moreover, developers can finally indent the text and the identifier:

$output = <<<EOT
        My
                name is:
        Hans.
        EOT;

The PHP interpreter first determines the number of tabs or spaces before the last identifier and then removes the same number of tabs or spaces padding each line of text above. In the above example $output contains the text My name is: Hans.

The ability to indent Heredoc and Nowdoc text makes the formatting of classes easier. Heredoc syntax formerly used to enforce this kind of code:

class Person {
        public $name = <<<EOT
Hans Hansen
EOT;
}

Thanks to PHP 7.3, the code can now take on a more pleasing arrangement:

class person {
        public $name = <<<EOT
        Hans Hansen
        EOT;
}

You can easily see that the second alignment is more intelligible.

Commas

In function calls, a comma can now occur after the last parameter, which allows programmers to append additional parameters easily, such as the call:

unset(
    $alt,
    $temp,
);

PHP programmers can also assign variables by reference in list(). The three-liner

$array = ["Hans", "Hansen"];
$firstname = $array[0];
$lastname =& $array[1];

can be written succinctly in PHP 7.3 as:

$array = [1, 2];
list($firstname, &$lastname) = $array;

Additions

Two new functions, array_key_first() and array_key_last(), determine the first and last keys in an array:

$name = ['Hans' => 1, 'Hansen' => 2];
echo array_key_first($name);

The hrtime() function returns the current system time in high resolution. Typically, this is the number of nanoseconds that have elapsed after a randomly determined reference point. The is_countable() function tests whether the variable passed in has countable content; it applies to arrays or objects that implement a Countable interface.

PHP 7.3 now also supports Argon2id hashes with the introduction of the PASSWORD_ARGON2ID hashing algorithm constant. The password_hash(), password_verify(), password_get_info(), and password_needs_rehash() functions now accept Argon2id hashes.

Bartering

To compare two strings, many developers convert their content to uppercase or lowercase, for which the extension for multibyte strings has several functions. For example, mb_strtoupper("Street"); returns the text STREET.

Special characters (e.g., the German Eszett) can sometimes cause problems, especially when compared. In addition to case mapping, case folding can occur, in which individual letters are replaced with other letters or even with a string of characters. In the case of the German Eszett, Straße would thus mutate to STRASSE.

In the current PHP version, all multibyte string functions such as mb_strtoupper() provide full support for case mapping and case folding. The conversion methods can be applied to a string with mb_convert_case().

Functions like mb_strtoupper() that eliminate upper and lower case, or just ignore it, now use the case folding method; for example, mb_strtoupper("Straße"); now returns STRASSE. As in this example, the string length can change.

In the background, all multibyte string functions use the new Unicode 11.0.0. PHP 7.3 now correctly supports multibyte strings that occupy more than 2GB of memory. Finally, the PHP authors have improved the performance of the Multibyte String extension. In particular, the functions that convert upper- and lowercase letters should now work far faster.

New Regulator

The popular PCRE extension allows the evaluation of Perl-compatible regular expressions. PHP 7.3 has removed the legacy PCRE and added its successor PCRE2, which partly changes the behavior when evaluating rules. PCRE2 interprets character ranges in (character) classes far more strictly than its predecessor. PHP developers will notice this especially with invalid patterns. Furthermore, PCRE2 is based on Unicode version 10.0 instead of Unicode 7.0. In PHP 7.3, the preg_quote() function now also masks the # character.

If you run an LDAP server, you have good reason to celebrate: The new PHP also supports LDAP controls. These objects can be used by all query functions, including ldap_add() and ldap_search(). Additionally, ldap_parse_result() in the $serverctrls parameter reads controls from a server.

PHP 7.3 supports the new JSON_THROW_ON_ERROR flag, which changes the error handling of json_decode() and json_encode(). Thanks to the new flag, the two functions from the JSON extension throw an exception when an error occurs.

Logger

The FastCGI Process Manager (FPM) now evaluates three additional settings for superior logging control. The global log_limit setting determines the maximum number of characters in a line the log lists. As of late, this can be more than 1,024 characters.

The global log_buffering setting enables logging without additional buffering, although the procedure is still considered experimental. Finally, the new pool option decorate_workers_output disables the output decoration of the worker output when catch_workers_output is enabled.

Deprecation by Installments

Finally, some features, functions, and syntax elements have been marked as deprecated. For example, PHP programmers should no longer declare constants that are case insensitive: PI and Pi are different constants in PHP 7.3. If you pass in TRUE as the third parameter in define(), and thus try to create a case-insensitive constant, you will now see a warning.

PHP provides several functions that search for a string in text and accept the text to be searched for in a parameter referred to as a "needle." From now on, the needle must consist of a string. The PHP authors recommend casting the needle into a string if in doubt or explicitly using the chr() function. Other functions affected by this change are strpos(), strrpos(), stripos(), strripos(), strstr(), strchr(), strrchr(), and stristr().

As of PHP 7.3, developers can no longer declare assert() within a namespace. The fgetss() and gzgetss() functions, the SplFileObject::fgetss() method, and the string.strip_tags stream filter are also considered obsolete. In the future, PHP programmers will also have to do without the FILTER _FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED constants. However, both are included in FILTER_VALIDATE_URL, which is still available.

The PHP team sorted out image2wbmp() and all the undocumented functions that start with mbereg_. Instead of the latter, PHP programmers should now use the mb_ereg_ functions. When accessing ODBC and DB2 databases via the PDO_ODBC driver, the pdo_odbc.db2_instance_name setting is history.

Expired

Support for PHP 5.6 and 7.0 was discontinued at the end of 2018, so the developers will no longer be fixing vulnerabilities in these versions. Various statistics show, however, that the old versions are still used on many websites. At the beginning of 2019, almost two thirds of all Joomla installations still ran PHP version 5.6 or earlier [2] (Figure 1) – a rough estimate, because not all Joomla site operators send their data to the developers.

PHP version legend clockwise from the orange section: versions 5.3-5.6 and 7.0-7.2.
Figure 1: PHP version legend clockwise from the orange section: versions 5.3-5.6 and 7.0-7.2.

Metasploit provider Rapid7 reports similarly worrying figures. As part of the Sonar project, Rapid7 regularly scans the Internet and collects information about the software in use. In December 2018, the statistics showed around 3 million sites with an outdated PHP version [3].

If you still have an older version, you should switch to the current PHP, if possible, because the days of PHP 7.1 are numbered. The developers are currently only providing security updates for this version, but this support will be terminated December 1, 2019 (Figure 2). The PHP team has actively supported only PHP 7.2 and 7.3 since January 1, 2019, with the first of these receiving only one year of security patches as of November 30, 2019 [4].

According to the timeline on the PHP website, the service life of PHP 5.5, 5.6, and 7.0 has already expired.
Figure 2: According to the timeline on the PHP website, the service life of PHP 5.5, 5.6, and 7.0 has already expired.

Conclusions

If you're starting a new PHP project, your best choice is version 7.3, which has some useful new features. Although manageable, the new kids on the block can disrupt existing software. Site operators and web developers are therefore well advised to adapt existing scripts, especially if PHP 5.6 or 7.0 is still in use. The PHP team has published a migration guide for programmers on its website that explains the differences between versions 7.2 and 7.3 [5].