PHP 7.2 and 7.3 Highlights

Posted by Spencer on September 3rd, 2019

Having recently researched migrating off of Mcrypt, I’m looking forward to seeing a codebase I work on make the leap from PHP 7.1 to 7.3. With large codebases like this one, upgrades can be a bit of a slog, so I find it helps to get excited about the benefits and changes that they bring. Here are some highlights that I’m personally looking forward to in the jump from 7.1 to 7.3!

You can of course read about all the changes in 7.2 and 7.3 in the PHP docs.

Warn when counting non-arrays (7.2)

Previously, doing count('foo') or count(4) would silently return 0. I have the sneaking suspicion there are edge cases we’re failing to notice and handle because of that behavior. Now, a warning will be emitted, which might help alert us to the existence of such cases, the same way 7.1’s addition of division by zero warnings did.

Argon2 (7.2, 7.3)

Argon2 is now the recommended hashing method for passwords. 7.2 adds support for Argon2i, and 7.3 builds on that with Argon2id, which offers better resistance to GPU cracking attacks.

Moar trailing commas! (7.2, 7.3)

This is a mostly aesthetic thing. I nearly always use trailing commas for arrays, because it makes the diff cleaner. It’s also useful when I need to quickly comment out the last item in an array.

PHP maintainers seem to like this as well, because they’ve added support for trailing commas in grouped namespaces (7.2) and for parameters in function calls (7.3).

Cleaner Heredoc syntax (7.3)

Indented closing marker! This is also mainly an aesthetic benefit, but I’m still excited!!

hrtime() (7.3)

I regularly use execution timing in my work in various ways when optimizing code and monitoring performance. More resilient/accurate timing is a good thing, particularly as our infrastructure evolves to include more exotic hosting setups.

Multibyte string perf (7.3)

Performance of the Multibyte String extension has been significantly improved across the board. The largest improvements are in case conversion functions.

Probably no surprise, we use many mb_ functions including for case case conversion, so this will be nice!

Array key helper funcs (7.3)

array_key_first() and array_key_last() will be more readable than code like array_keys($array)[count($array)-1], making these small but nice additions.

setcookie() params as array and HTTP SameSite (7.3)

Can you tell without referring to the manual what the null and boolean options here do?

setcookie('my_cookie', 'my_value', null, '/foo/', null, false, true);

Of course not! Seven parameters are too many for anyone to keep track of, especially when their values might leave no clues. With 7.3, the third parameter can now (optionally) be an associative array containing all of the other options, which encourages more human-parseable code.

$options = [
    'expires' => null,
    'path' => '/foo/',
    'domain' => null,
    'secure' => false,
    'httponly' => true,
];

setcookie('my_cookie', 'my_value', $options);

This was likely inspired by what would have otherwise been an eighth argument for the new SameSite cookie attribute- which 7.3 has added support for.

JSON exceptions (7.3)

JSON decoding has funky global error handling. For instance, when parsing potentially malformed JSON, you might have needed to add awkward code like this:

$foo = json_decode($my_string, true);
if (json_last_error() != JSON_ERROR_NONE) {
    // handle the error
}

Now you can opt into letting the JSON decoder simply throw an exception, which in some cases may be a more natural way to handle an error.

try {
    $foo = json_decode($my_string, true, null, JSON_THROW_ON_ERROR);
}
catch (JsonException as $exception) {
    // handle error
}

Generally speaking, throwing named exceptions is a useful way to provide context to functions up the tree, so that they can handle the error as they see fit.

Summary

Updating from 7.1 to 7.3 brings several useful improvements to the language that will further promote code readability, speed, and security.

Posted in Coding