Professional Documents
Culture Documents
io
Scout APM helps PHP developers pinpoint N+1 queries, memory leaks & more so you
can troubleshoot fast & get back to coding faster. Start your free 14-day trial today.
PHP 8 is here! It was released on November 26, 2020. You can download it
here. It's a new major version, which means that it will introduce some
breaking changes, as well as lots of new features and performance
improvements.
Besides breaking changes, PHP 8 also brings a nice set of new features
such as the JIT compiler, union types, attributes, and more.
New features
Let's start with all new features, it's quite a list!
https://stitcher.io/blog/new-in-php-8 1/29
25/01/2021 What's new in PHP 8 - stitcher.io
Given the dynamically typed nature of PHP, there are lots of cases where
union types can be useful. Union types are a collection of two or more
types which indicate that either one of those can be used.
Note that void can never be part of a union type, since it indicates "no
return value at all". Furthermore, nullable unions can be written using
|null , or by using the existing ? notation:
JIT rfc
https://stitcher.io/blog/new-in-php-8 2/29
25/01/2021 What's new in PHP 8 - stitcher.io
If you want to know more about what the JIT can do for PHP, you can read
another post I wrote about it here.
Interested in more?
I'm writing a new series on how I manage and grow my blog called "Blogs for
Devs". You might like the behind the scenes stories and also be inspired to
start your own blog.
Check it out!
If you're familiar with the null coalescing operator you're already familiar
with its shortcomings: it doesn't work on method calls. Instead you need
intermediate checks, or rely on optional helpers provided by some
frameworks:
$startDate = $booking->getStartDate();
https://stitcher.io/blog/new-in-php-8 3/29
25/01/2021 What's new in PHP 8 - stitcher.io
With the addition of the nullsafe operator, we can now have null coalescing-
like behaviour on methods!
$dateAsString = $booking->getStartDate()?->asDateTimeString();
foo(
b: 'value b',
a: 'value a',
d: 'value d',
);
https://stitcher.io/blog/new-in-php-8 4/29
25/01/2021 What's new in PHP 8 - stitcher.io
Attributes rfc
As for a quick look, here's an example of what attributes look like, from the
RFC:
use App\Attributes\ExampleAttribute;
#[ExampleAttribute]
class Foo
{
#[ExampleAttribute]
public const FOO = 'foo';
#[ExampleAttribute]
public $x;
#[ExampleAttribute]
public function foo(#[ExampleAttribute] $bar) { }
}
#[Attribute]
class ExampleAttribute
{
public $value;
https://stitcher.io/blog/new-in-php-8 5/29
25/01/2021 What's new in PHP 8 - stitcher.io
}
}
Noticed a tpyo? You can submit a PR to fix it. If you want to stay up to date
about what's happening on this blog, you can follow me on Twitter or
subscribe to my newsletter:
Email Subscribe
You could call it the big brother of the switch expression: match can
return values, doesn't require break statements, can combine conditions,
uses strict type comparisons and doesn't do any type coercion.
$result = match($input) {
0 => "hello",
'1', '2', '3' => "world",
};
https://stitcher.io/blog/new-in-php-8 6/29
25/01/2021 What's new in PHP 8 - stitcher.io
This RFC adds syntactic sugar to create value objects or data transfer
objects. Instead of specifying class properties and a constructor for them,
PHP can now combine them into one.
class Money
{
public Currency $currency;
class Money
{
public function __construct(
public Currency $currency,
public int $amount,
https://stitcher.io/blog/new-in-php-8 7/29
25/01/2021 What's new in PHP 8 - stitcher.io
) {}
}
There's a lot more to tell about property promotion, you can read about
them in this dedicated post.
While it was already possible to return self , static wasn't a valid return
type until PHP 8. Given PHP's dynamically typed nature, it's a feature that
will be useful to many developers.
class Foo
{
public function test(): static
{
return new static();
}
}
Some might call it a necessary evil: the mixed type causes many to have
mixed feelings. There's a very good argument to make for it though: a
missing type can mean lots of things in PHP:
https://stitcher.io/blog/new-in-php-8 8/29
25/01/2021 What's new in PHP 8 - stitcher.io
Because of the reasons above, it's a good thing the mixed type is added.
mixed itself means one of these types:
array
bool
callable
int
float
null
object
resource
string
Note that mixed can also be used as a parameter or property type, not just
as a return type.
Also note that since mixed already includes null , it's not allowed to make
it nullable. The following will trigger an error:
// Fatal error: Mixed types cannot be nullable, null is already part of the m
function bar(): ?mixed {}
https://stitcher.io/blog/new-in-php-8 9/29
25/01/2021 What's new in PHP 8 - stitcher.io
This RFC changed that behaviour, so that these inheritance checks are not
performed on private methods anymore. Furthermore, the use of final
private function also didn't make sense, so doing so will now trigger a
warning:
Warning: Private methods cannot be final as they are never overridden by othe
https://stitcher.io/blog/new-in-php-8 10/29
25/01/2021 What's new in PHP 8 - stitcher.io
Built upon the weakrefs RFC that was added in PHP 7.4, a WeakMap
implementation is added in PHP 8. WeakMap holds references to objects,
which don't prevent those objects from being garbage collected.
Take the example of ORMs, they often implement caches which hold
references to entity classes to improve the performance of relations
between entities. These entity objects can not be garbage collected, as
long as this cache has a reference to them, even if the cache is the only
thing referencing them.
If this caching layer uses weak references and maps instead, PHP will
garbage collect these objects when nothing else references them anymore.
Especially in the case of ORMs, which can manage several hundreds, if not
thousands of entities within a request; weak maps can offer a better, more
resource friendly way of dealing with these objects.
Here's what weak maps look like, an example from the RFC:
class Foo
{
private WeakMap $cache;
https://stitcher.io/blog/new-in-php-8 11/29
25/01/2021 What's new in PHP 8 - stitcher.io
A small, yet useful, new feature: it's now possible to use ::class on
objects, instead of having to use get_class() on them. It works the same
way as get_class() .
var_dump($foo::class);
try {
// Something goes wrong
} catch (MySpecialException $exception) {
Log::error("Something went wrong");
}
https://stitcher.io/blog/new-in-php-8 12/29
25/01/2021 What's new in PHP 8 - stitcher.io
try {
// Something goes wrong
} catch (MySpecialException) {
Log::error("Something went wrong");
}
Note that it's required to always specify the type, you're not allowed to have
an empty catch . If you want to catch all exceptions and errors, you can
use Throwable as the catching type.
Already possible when calling a function, trailing comma support was still
lacking in parameter lists. It's now allowed in PHP 8, meaning you can do
the following:
public function(
string $parameterA,
int $parameterB,
Foo $objectfoo,
) {
// …
}
https://stitcher.io/blog/new-in-php-8 13/29
25/01/2021 What's new in PHP 8 - stitcher.io
DateTime::createFromInterface(DateTimeInterface $other);
DateTimeImmutable::createFromInterface(DateTimeInterface $other);
class Foo
{
public function __toString(): string
{
return 'foo';
}
}
https://stitcher.io/blog/new-in-php-8 14/29
25/01/2021 What's new in PHP 8 - stitcher.io
bar(new Foo());
bar('abc');
Some might say it's long overdue, but we finally don't have to rely on
strpos() anymore to know whether a string contains another string.
Two other ones long overdue, these two functions are now added in the
core.
https://stitcher.io/blog/new-in-php-8 15/29
25/01/2021 What's new in PHP 8 - stitcher.io
The new fdiv() function does something similar as the fmod() and
intdiv() functions, which allows for division by 0. Instead of errors you'll
get INF , -INF or NAN , depending on the case.
https://stitcher.io/blog/new-in-php-8 16/29
25/01/2021 What's new in PHP 8 - stitcher.io
Each one of those resources gets assigned an ID, though previously the
only way to know that id was to cast the resource to int :
$resourceId = get_resource_id($resource);
trait Test {
abstract public function test(int $input): int;
}
class UsesTrait
{
use Test;
https://stitcher.io/blog/new-in-php-8 17/29
25/01/2021 What's new in PHP 8 - stitcher.io
PHP 8 will perform proper method signature validation when using a trait
and implementing its abstract methods. This means you'll need to write this
instead:
class UsesTrait
{
use Test;
https://stitcher.io/blog/new-in-php-8 18/29
25/01/2021 What's new in PHP 8 - stitcher.io
From the RFC: "the Uniform Variable Syntax RFC resolved a number of
inconsistencies in PHP's variable syntax. This RFC intends to address a
small handful of cases that were overlooked."
Breaking changes
As mentioned before: this is a major update and thus there will be breaking
changes. The best thing to do is take a look at the full list of breaking
changes over at the UPGRADING document.
https://stitcher.io/blog/new-in-php-8 19/29
25/01/2021 What's new in PHP 8 - stitcher.io
Lots of errors that previously only triggered warnings or notices, have been
converted to proper errors. The following warnings were changed.
https://stitcher.io/blog/new-in-php-8 21/29
25/01/2021 What's new in PHP 8 - stitcher.io
From the RFC: The current default error mode for PDO is silent. This
means that when an SQL error occurs, no errors or warnings may be
emitted and no exceptions thrown unless the developer implements their
own explicit error handling.
While already deprecated in PHP 7.4, this change is now taken into effect.
If you'd write something like this:
https://stitcher.io/blog/new-in-php-8 22/29
25/01/2021 What's new in PHP 8 - stitcher.io
[] % [42];
$object + 4;
https://stitcher.io/blog/new-in-php-8 23/29
25/01/2021 What's new in PHP 8 - stitcher.io
This RFC fixes the very strange case in PHP where 0 == "foo" results in
true . There are some other edge cases like that one, and this RFC fixes
them.
Reflection changes
A few reflection methods have been deprecated:
ReflectionFunction::isDisabled()
ReflectionParameter::getClass()
ReflectionParameter::isCallable()
https://stitcher.io/blog/new-in-php-8 24/29
25/01/2021 What's new in PHP 8 - stitcher.io
$reflectionParameter->getType()->allowsNull();
$reflectionParameter->getType()->getName();
$reflectionParameter->getType()->isBuiltin();
$reflectionParameter->getType()->getTypes();
https://stitcher.io/blog/new-in-php-8 25/29
25/01/2021 What's new in PHP 8 - stitcher.io
Next up, three method signatures of reflection classes have been changed:
ReflectionClass::newInstance($args);
ReflectionFunction::invoke($args);
ReflectionMethod::invoke($object, $args);
ReflectionClass::newInstance(...$args);
ReflectionFunction::invoke(...$args);
ReflectionMethod::invoke($object, ...$args);
The upgrading guide specifies that if you extend these classes, and still
want to support both PHP 7 and PHP 8, the following signatures are
allowed:
https://stitcher.io/blog/new-in-php-8 26/29
25/01/2021 What's new in PHP 8 - stitcher.io
Interested in more?
I'm writing a new series on how I manage and grow my blog called "Blogs for
Devs". You might like the behind the scenes stories and also be inspired to
start your own blog.
Check it out!
Before PHP 8, sorting algorithms were unstable. This means that the order
of equal elements wasn't guaranteed. PHP 8 changes the behaviour of all
sorting functions to stable sorting.
https://stitcher.io/blog/new-in-php-8 27/29
25/01/2021 What's new in PHP 8 - stitcher.io
During the PHP 7.* development, several deprecations were added that are
now finalised in PHP 8.
Noticed a tpyo? You can submit a PR to fix it. If you want to stay up to date
about what's happening on this blog, you can follow me on Twitter or
subscribe to my newsletter:
Email Subscribe
Footnotes
Upgrading to PHP 8 using Homebrew on a Mac
The nullsafe operator
The match operator in PHP 8
Named arguments in PHP 8
Property promotion in PHP 8
The latest PHP version — how modern PHP versions are managed
Attributes in PHP 8 — A close look at attributes, also known as
annotations
PHP in 2020
What's new in PHP 7.4
What's new in PHP 7.3
https://stitcher.io/blog/new-in-php-8 28/29
25/01/2021 What's new in PHP 8 - stitcher.io
https://stitcher.io/blog/new-in-php-8 29/29