New features of PHP 8

Time:2021-5-8
New features of PHP 8
 

The new major PHP version, PHP 8, is expected to be released by the end of 2020. It’s in a very active development phase now, so things could change a lot in the next few months.

In this article, I’ll keep updating my list of expected content: new features, performance improvements, and major changes. Because PHP 8 is a new major version, your code is more likely to be damaged. If you’ve been updating the latest version, it shouldn’t be too difficult to upgrade, because most of the disruptive changes were obsolete before 7* edition.

In addition to interrupt changes, PHP 8 also brings some nice new features, such as JIT compiler and union type; There’s more!

Union types: Union types

Given the dynamic typing nature of PHP, it is useful to union types in many cases. A union type is a collection of two or more types that indicate that one of them can be used.

public function foo(Foo|Bar $input): int|float;

Note that void can never be part of a union type because it means “no return value at all.”. In addition, you can use | null to write a nullable Union, or you can use an existing? Symbol:

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
JIT

Instant compilers promise significant performance improvements, though not always in the context of web requests. There are no precise benchmarks yet, but they are sure to come.

Static return type: static return type

Although self can be returned, the static type does not become a valid return type until PHP 8. Given PHP’s dynamic typing feature, this feature is useful to many developers.

class Foo
{
    public function test(): static
    {
        return new static();
    }
}
Weak maps

Based on the weakrefs RFC added in PHP 7.4, the weakmap implementation is added in PHP 8. Weak maps contain references to objects, which does not prevent those objects from being garbage collected.

Taking ORM as an example, they usually implement caching of references to entity classes to improve the performance of relationships between entities. These entity objects cannot be garbage collected as long as the cache has a reference to them, even if the cache is the only thing that references them.

If the cache layer uses weak references and mappings, PHP will garbage collect objects when no other objects refer to them. ORM, in particular, can manage hundreds (if not thousands) of entities in a single request; Weak mapping provides a better and resource friendly way to deal with these objects.

Here’s what a weak mapping looks like, an example from RFC:

class Foo 
{
    private WeakMap $cache;

    public function getSomethingWithCaching(object $obj): object
    {
        return $this->cache[$obj]
           ??= $this->computeSomethingExpensive($obj);
    }
}
::class on objects

A small and useful new feature: you can now use:: class on objects instead of get on them_ class()。 How it works and how it works_ Class () is the same.

$foo = new Foo();

var_dump($foo::class);
Stringable interface

The stringable interface can be used to type any string or implement theThe content of tostring(). Moreover, whenever the class implementsToString (), which will automatically implement the interface in the background, does not need to be implemented manually.

class Foo
{
    public function __toString(): string
    {
        return 'foo';
    }
}

function bar(Stringable $stringable) { /* … */ }

bar(new Foo());
bar('abc');
Creating a datetime object from an interface

You can already use datetime:: create from immutable datetime ($immutable datetime) to create a datetime object from a datetime object, but the other method is cumbersome. By adding datetime:: createfrominterface() and datetime:: createfrominterface(), there is now a general way to convert datetime and datetime objects to each other.

DateTime::createFromInterface(DateTimeInterface $other);

DateTimeImmutable::createFromInterface(DateTimeInterface $other);
Warning to redefine engine

Many errors that used to trigger only warnings or notifications have now been converted to correct errors. The following warning has been changed.

  • Undefined variable: Error exception instead of notice
  • Undefined array index: warning instead of notice
  • Division by zero: DivisionByZeroError exception instead of warning
  • Attempt to increment/decrement property ‘%s’ of non-object: Error exception instead of warning
  • Attempt to modify property ‘%s’ of non-object: Error exception instead of warning
  • Attempt to assign property ‘%s’ of non-object: Error exception instead of warning
  • Creating default object from empty value: Error exception instead of warning
  • Trying to get property ‘%s’ of non-object: warning instead of notice
  • Undefined property: %s::$%s: warning instead of notice
  • Cannot add element to the array as the next element is already occupied: Error exception instead of warning
  • Cannot unset offset in a non-array variable: Error exception instead of warning
  • Cannot use a scalar value as an array: Error exception instead of warning
  • Only arrays and Traversables can be unpacked: TypeError exception instead of warning
  • Invalid argument supplied for foreach(): TypeError exception instead of warning
  • Illegal offset type: TypeError exception instead of warning
  • Illegal offset type in isset or empty: TypeError exception instead of warning
  • Illegal offset type in unset: TypeError exception instead of warning
  • Array to string conversion: warning instead of notice
  • Resource ID#%d used as offset, casting to integer (%d): warning instead of notice
  • String offset cast occurred: warning instead of notice
  • Uninitialized string offset: %d: warning instead of notice
  • Cannot assign an empty string to a string offset: Error exception instead of warning