PHP, aka Hypertext Preprocessor, is a popular open-source server-side scripting language used for web design and development. Its new major version, PHP 8.0, will be released to the public by the end of this year and will bring some very exciting new enhancements.
So, without further ado, let’s cast a look at some of the top expected enhancements. But, before I do that, let me clarify: PHP 8.0 is in very active development right now, meaning many things in this post are likely to change a lot in the upcoming months. If you’re looking for a fresh up-to-date list, please refer to the UPGRADING file in the official repo.
With that said, let’s roll.
Union Types 2.0 (RFC)
A “union type” accepts values of multiple different types rather than a single one. Arbitrary union types are currently not supported by PHP; instead, phpdoc annotations have to be used. Given PHP’s dynamically typed nature, there are lots of cases where union types can be useful.
JIT (RFC): Just in Time Compiler
Well, it was about time; I don’t think there are any optimization strategies left that can further improve the performance of PHP unless JIT is used. There haven’t been many accurate benchmarks done currently; however, I did come across the Mandelbrot benchmark, which claims this change is 4x faster. It promises significant performance improvements, albeit not always within the context of web requests.
Moreover, using JIT may open the door for the language being more frequently used in other, non-Web, CPU-intensive scenarios – where the performance benefits will actually be very substantial – and for which the language is probably not even being considered today.
The static return type (RFC)
While it was already possible to make self a return type for functions, the static return RFC aims to make static also an available return type. Given the dynamically typed nature of PHP, it’s a feature that many developers will appreciate.
Weak maps (RFC)
Built upon the weak references RFC introduced in PHP 7.4, a WeakMap implementation is added in PHP 8.0. Much more commonly used in practice, WeakMaps hold references to objects, which don’t prevent those objects from being garbage collected.
For instance, we take ORMs (Object-relational mapping); they often implement caches that hold references to entity classes to improve relations performance between entities. These entity objects are prevented from being garbage collected as long as this cache has a reference to them (even if it’s the only thing referencing them).
If this caching layer utilizes weakrefs and maps instead, these objects will be garbage collected by PHP when nothing else references them anymore. Especially in object-relational mappings, which can manage several hundreds of entities within a request, WeakMap can offer an efficient, more resource-friendly way of dealing with these objects.
Create DateTime objects from the interface
Well, it was possible already to create a DateTime object from a DateTimeImmutable object using DateTime::createFromImmutable($immutableDateTime), but unfortunately, this wasn’t so easy the other way around. With the addition of DateTime::createFromInterface() and DatetimeImmutable::createFromInterface() there’s now a generalized way to convert a DateTime object into a DateTimeImmutable object and vice versa.
:: class on objects RFC
A small, yet useful, new feature: it’s now possible to use::class on objects, instead of using get_class() on them. It works the same way as get_class().
fdiv function PR
Functioning similar to the fmod and intdiv functions, the new fdiv function allows for division by 0. Instead of errors, you’ll get INF, -INF, or NAN, depending on the case.
Stringable interface RFC
The Stringable interface can type-hint anything that is a string or implements __toString(). Furthermore, whenever a class implements __toString(), it automatically implements the interface behind the scenes, and there’s no need to implement it manually.
Well, since it’s a major update thus, there will be breaking changes too. I’ll mention the essential ones here, but you can take a look at the full list of breaking changes by going over to the UPGRADING document.
Consistent type errors RFC
Previously, user-defined functions would throw TypeErrors, but internal functions did not; they rather emitted warnings and returned null. As of PHP 8.0, the internal function’s behavior has been made consistent.
Reclassified engine warnings RFC
Several errors that used to trigger only warnings or notices have been converted to proper errors. A lot of warnings were changed; I’ve only mentioned a few here:
- Undefined variable: Error exception instead of notice
- Division by zero: DivisionByZeroError exception instead of warning
- Attempt to modify property ‘%s’ of non-object: Error exception instead of warning
- Cannot unset offset in a non-array variable: Error exception instead of warning
- Array to string conversion: warning instead of notice
- Cannot assign an empty string to a string offset: Error exception instead of warning
- And so on.
Default error reporting level
It’s now E_ALL instead of everything but E_NOTICE and E_DEPRECATED. Many errors might pop up that were previously silently ignored, though probably already existent in this new major version.
The @ operator no longer silences fatal errors.
This change might reveal errors that again were hidden before PHP 8.0. Make sure to set display_errors=Off on your production servers!