PHP 8.0 - What's new in the latest release

4 min read

PHP 8

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.

Named arguments RFC

  • Specify only required parameters, skipping optional ones.
  • Arguments are order-independent and self-documented.
// PHP7

htmlspecialchars(
  $string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false
  );
// PHP8

htmlspecialchars($string, double_encode: false);

Union types RFC

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.

// PHP7

class Number {
  /** @var int|float */
  private $number;

  /**
   * @param float|int $number
   */
  public function __construct($number) {
    $this->number = $number;
  }
}

new Number('NaN'); // Ok

Instead of PHPDoc annotations for a combination of types, you can use native union type declarations that are validated at runtime.

// PHP8

class Number {
  public function __construct(
    private int|float $number
  ) {}
}

new Number('NaN'); // TypeError

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:

// PHP8

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

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

Attributes RFC

Attributes, commonly known as annotations in other languages, offers a way to add meta data to classes, without having to parse docblocks. Instead of PHPDoc annotations, you can now use structured metadata with PHP’s native syntax.

// PHP7

class PostsController
{
    /**
     * @Route("/api/posts/{id}", methods={"GET"})
     */
    public function get($id) { /* ... */ }
}
// PHP8

class PostsController
{
    #[Route("/api/posts/{id}", methods: ["GET"])]
    public function get($id) { /* ... */ }
}

The nullsafe operator RFC

Instead of null check conditions, you can now use a chain of calls with the new nullsafe operator. When the evaluation of one element in the chain fails, the execution of the entire chain aborts and the entire chain evaluates to null.

// PHP7

$country =  null;

if ($session !== null) {
  $user = $session->user;

  if ($user !== null) {
    $address = $user->getAddress();

    if ($address !== null) {
      $country = $address->country;
    }
  }
}
// PHP8

$country = $session?->user?->getAddress()?->country;

Constructor property promotion RFC

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.

// PHP7

class Money
{
  public Currency $currency;

  public int $amount;

  public function __construct(
      Currency $currency,
      int $amount,
  ) {
      $this->currency = $currency;
      $this->amount = $amount;
  }
}
// PHP8

class Money
{
    public function __construct(
        public Currency $currency,
        public int $amount,
    ) {}
}

JIT RFC

PHP 8 introduces two JIT compilation engines. Tracing JIT, the most promising of the two, shows about 3 times better performance on synthetic benchmarks and 1.5–2 times improvement on some specific long-running applications. Typical application performance is on par with PHP 7.4.

Here is a benchmarks

on real-life web applications, and it seems like the JIT doesn’t make that much of a difference, if any, on those kinds of PHP projects.If you want to know more about what the JIT can do for PHP, you can read another post about it here .

Of course, these are just the highlights. Check out the official release announcement or the following post for all the details.

  • #php
  • #php8
  • #highlights
  • #jit
  • #new
  • #release
  • #backend