PHP 8 - What's New?
The release of PHP 8 has been making circles on the web for quite some time now, and although there are still almost two months to go, we already know what’s new and which of the changes can make it really hard to seamlessly switch from PHP 7 to the most recent release.
Recently, the last of the four planned beta versions was released – this means that until the planned release date on 26 November 2020, we are still in for four Release Candidate versions.
In our agency, where we provide Drupal services on a daily basis, as well as Drupal support, and in our team we have many PHP developers, we closely observe all the news and therefore in the text below we present the most important changes that will be introduced by version 8.
Union types
It is a nod to static typing while maintaining the dynamic nature of the language. The Union allows you to define a set of types (two or more), both for input and output data. Until now, the syntax of the language did not allow for the use of the Union, and this problem has been circumvented by defining types in annotations.
class Example {
private int|string $id;
public function setId(int|string $id): void {
$this->id = $id;
}
public function getId(): int|string {
return $this->id;
}
}
Defining a void type among the returned types is unacceptable because this type already specifies that the function does not return any value. However, we can easily define null to denote the so-called nullable values.
Named arguments
This is a problem that many PHP programmers have encountered in their development work, who often had to use methods or functions that take have more optional arguments, many of which have default values. Until now, they had no other choice but to copy all the preceding default values from a function in the same order to assign their own value to one of the arguments. Named arguments allow passing a parameter based on its name, instead of the order.
foo(string $b, ?string $a, ?string $r): {
}
Example::foo(
b: 'Foo',
r: 'Bar',
);
Constructor property promotion
If assigning multiple arguments in the constructor to the object properties made you lose your sleep, you can rest assured – in PHP 8 this will never happen again. Although this is hardly more than syntactic sugar, this feature will certainly increase clarity many classes in your application. Below is a comparison of constructors in PHP 7 and PHP 8.
// PHP 7
class Example {
public Foo $foo;
protected Bar $bar;
public function __construct(
Foo $foo,
Bar $bar
) {
$this->foo = $foo;
$this->bar = $bar;
}
}
// PHP 8
class Example {
public function __construct(
public Foo $foo,
protected Bar $bar,
) {}
}
Attributes
Some know them as annotations, which to date were created only in the form of comments (read by dedicated libraries such as Doctrine ORM) — finally, they have been promoted to being an actual and official part of the language. After a fierce battle about how annotations should be marked, two greater-than signs sign was chosen as the opening, with less-than signs used to close the attribute.
use Php\Attributes\Deprecated;
<<Deprecated("Use bar() instead")>>
function foo() {}
Match expression
Although the name of this new functionality may seem to suggest a certain link with regular expressions, it is rather close to the switch command. Thanks to this mechanism, developers will be able to return the value based on the input parameter, without using additional keywords, i.e. break, return. What is more, Match uses strong typing to compare values (similar to using the === comparison expression), and if none of the cases are met, the UnhandeledMatchError exception is thrown by default.
$controller = match ($status_code) {
200 => new PageController(),
301, 302, 303 => new RedirectController(),
404 => new PageNotFoundController(),
};
JIT (Just in time compiler)
The mechanism, which has been available for testing since PHP 7.4, finally got its official release. JIT is nothing more than compiling into machine code immediately before it is executed. In practice, this allows you to execute the application code "on the fly", faster than with a traditional interpreter. This can be compared to caching code that was already interpreted.
For those who know Hack and HHVM (HipHop Virtual Machine) created by facebook.com developers, JIT is hardly something to call home about. In the PHP world, before PHP 8 was to be released, the developers continued to make attempts to improve performance by all available means without using JIT. The lack of any actual areas for improvement forced their hand to follow in the footsteps of our Facebook colleagues.
To learn more about Jit, check out my Jit in PHP article.
Other new features
Among the novelties that PHP 8 will offer us, we will find a few more minor functionalities that may also be interesting for new businesses - PHP is considered as the perfect solution for startups.
- nullsafe operator - equivalent of null coalescing operator for methods e.g. $item->getField()?->getValue();
- static - added as returned value type, previously only self was available;
- mixed - a new value type, which means the same as the known mixed value in the comments, which is any simple type;
- WeakMaps - a mechanism for storing references, which at the same time allows for their removal by the garbage collector;
- using the magic ::class method on objects – allows you to obtain the same value as returned from the get_class() function;
- trailing comma in the list of function parameters;
- handling exceptions without the need for them to be assigned to a variable;
- new Stringable interface – automatically assigned to all classes that implement __toString() method;
- validation of abstract methods derived from traits.
New features
In addition to the changes in language syntax mentioned so far, the release of PHP 8 adds a number of useful new features, which – truth be told – mostly make up the so-called syntactic sugar, but at the same time, they significantly increase the comfort of everyday work with the language. The most important of these are:
str_contains()
Because everybody had to check if a given string contains some defined subphrase using the strpos function and check if the returned value was different from FALSE. The str_contains function can do this check in the background.
str_starts_with() and str_ends_with()
Both functions do exactly what the box says – they check whether a string starts or ends with a certain value.
get_debug_type()
This function extends the gettype() function – except it returns the exact type as defined in the code, for example, int instead of an integer, float instead of double, or \Foo\Bar instead of object.
General changes
Since it is a new main version, it is also going to introduce a couple of changes to the existing language elements. In PHP 8, we can see a clear step towards making everything clear and transparent, so that they are more predictable and do not cause unnecessary confusion.
Important changes include returning TypeError and ValueError exceptions for embedded functions. The mechanisms used to compare variables of different kinds, concatenation order or verification of types for arithmetic and bit operations were improved. The ability to statically call methods that are not static was removed.
In addition, functions such as create_function() and each() were removed, while mechanisms of other functions, including array_key_exists() and define() were changed.
Important changes have also been made to the default mechanisms for error handling and displaying. The default value for error reporting will be E_ALL, and the @ operator will no longer mask critical errors.
Conclusions
The new version of PHP 8 is a sure step towards tidying up the language and a release that brings many long-awaited features.
In this article, I summed up the key changes and what we can expect and what may be important in the context of implementing PHP development services. However, I would definitely love to shed more light on JIT compiler, which is featured on our blog in a separate article.