Ashley Sheridan​.co.uk

PHP 7.3 Upcoming Features

Posted on

Although PHP 7.3 doesn't have a released spec yet, it's a fairly good bet looking at the list of approved RFC documents at what we can expect in the next release of PHP 7.

Exceptions with JSON Errors

The two main JSON functions, json_encode() and json_decode(), have always had poor error handling, forcing developers to rely on calling the json_last_error() function to determine whether the returned null value was an error or a genuine return value.

The proposed solution is to pass in a JSON_THROW_ON_ERROR flag, which instructs the JSON functions to throw a JsonException exception when encountering an error.

try { json_decode("{invalid json", true, 512, JSON_THROW_ON_ERROR); } catch (\JsonException $exception) { // do something with $exception here }

The JSON throw on error RFC has indicated that there should be no backwards compatibility issues unless you've got your own JsonException or JSON_THROW_ON_ERROR specified in userland code.

Allow a Trailing Comma in Function Calls

Trailing commas in arrays have virtually always been a part of PHP, and for the same reason, they are going to be added to function calls. The given example makes a lot of sense:

unset( $somethingIDontNeedAnymore, $anotherOneToKill, $letsMakeThisEasy, );

An interesting bit of trivia on this one, it was originally meant to make it into PHP 7.2, but due to an oversight it got left out!

The trailing comma RFC says there are no backwards compatibility issues whatsoever.

Flexible Heredoc and Nowdoc Syntaxes

One major gripe that people have had with the syntax of Heredoc and Nowdoc is that the syntax was very rigid, and it would often cause code to look ugly because of the forced lack of indentation.

The new spec proposes two new changes; closer marker indentation, and closing marker new line.

Indentation

Previously, if you were using Heredoc, you might have code that looks like the following:

class some_class { function print_message() { echo <<<MESSAGE; Message here all flush against the margin because we don't want whitespace in our output MESSAGE; } }

Now, you can indent both message and the closing marker, and that extra whitespace will automatically be removed.

class some_class { function print_message() { echo <<<MESSAGE; Message here all flush against the margin because we don't want whitespace in our output MESSAGE; } }

There are some caveats with this: you can't indent the marker more than the most indented line of the string, and you can't mix and match tabs and spaces in the indents of the string and the closing marker. This last one should be obvious though.

Newline on Closing Marker

Currently, a Heredoc or Nowdoc block must be terminated by a new line. This potentially resulted in code like this:

$values = [<<<END a b c END , 'd e f', <<<END g h i END , 'j k l'];

The new change would neaten that up to:

$values = [<<<END a b c END, 'd e f', <<<END g h i END, 'j k l'];

Nothing too ground breaking, but welcome nonetheless. The only major issue here is that if your closing marker happens to be at the start of one of the string lines, then the block will terminate early, and cause an error with the rest of the code.

Essentially all of the changes here are effectively breaking, as per the flexible Heredoc & Nowdoc RFC. Don't let this dissuade you from using the new syntax on the latest version of PHP, as it will make your code a lot tidier.

New is_countable() Function

One of the new features of PHP 7.2 was to introduce warnings when calling count() on any variable that doesn't support it. The fix was to check if the variable implemented the Countable interface, or if it was an array. Because this is a bit of a pain, 7.3 adds the is_countable() function to do the work for you.

As this is a brand new function, there are no incompatible breaking changes from this feature.

Arrays Starting with Negative Index

Currently, when creating arrays or inserting elements into an array, the next index is automatically generated as the previous max index + 1, or 0 if that is less than zero.

The proposed change which looks set to begin a deprecation phase in PHP 7.3 will allow negative array indexes in these cases. The proposed negative array index RFC highlights the following as all producing the same array:

// code $a = array_fill(-2, 3, true); $b = [-2 => true, true, true]; $c = ["string" => true, -2 => true, true, true]; unset($c["string"]); $d[-2] = true; $d[] = true; $d[] = true; // result array(3) { [-2]=> bool(true) [0]=> bool(true) [1]=> bool(true) }

This has quite a drastic breaking change, so only a deprecation notice will be issued for 7.3. It's unclear how long this phase will last, but given PHPs history, it could be years! It's worth keeping an eye out on this one. If you do have code that might have issues with this, then it's worth updating anyway because, frankly, that's weird behaviour to rely on!

Some Features That Didn't Make It

UUID

Quite why this didn't make the cut is anyones guess, especially given that the UUID functionality already exists in plenty of other languages. Hopefully this RFC is not completely dead in the water, as this is a feature that would be incredibly useful as a built in function, instead of having to rely on system calls (not very portable), or userland code. UUIDs can play a great part in security, and when it comes to security, the more that can be moved out of userland code and into core is better.

SameSite is a flag on cookies that help protect against CSRF. Again, quite why this one was not approved is a mystery. All is not completely lost, you can still output the same cookie header (supported by the most recent versions of Chrome, Opera, and Firefox) by overloading the value you pass into the domain or path. Obviously, this is not ideal, so this may again be revisted by the PHP team to feature in a future version.

sqliteOpenBlob() Support in PDO

The PDO library is probably the most common method to communicate with databases in use by PHP today. The idea is to create a common library that allows the backend database to be exchanged more easily. While this is unlikely to happen in practice, having a library that offers all of the standard functionality via a standard interface is a great ideal.

The sqliteOpenBlob RFC proposes to add this missing functionality, although it didn't get enough votes to pass, possibly because the same effect can be achieved with PDO LOBs (although not as efficiently). I'm not too concerned about this one, as it's not a killer feature.

Conclusion

There are some nice new changes coming in PHP 7.3; nothing that will change the world, but nice all the same. It is a shame that two very key features for security didn't have the number of votes needed to progress though. This might not mean they're dead in the water; the optimist in me believes that the features will make it in, but perhaps in a more prominent version, not a minor update.