DEV Community

Cover image for PHP 8 New features & comparison with older versions.
Dannyvpz
Dannyvpz

Posted on • Updated on

PHP 8 New features & comparison with older versions.

PHP 8.0 is a major update of the PHP language.
It contains many new features and optimizations including named arguments, union types, attributes, constructor property promotion, match expression, nullsafe operator, JIT, and improvements in the type system, error handling, and consistency...

Table of contents

===

  1. JIT Compiler.
  2. PHP 8 New Features.
  3. PHP 8 impact & compatibility (with Wordpress).
  4. Deprecated functions.

1. The JIT (just-in-time) compiler

===
When PHP code is run, it's usually done by compiling & executed in a virtual machine. JIT will change this by compiling the code into x86 machine code and then running that code directly on the CPU.
For applications that rely heavily on mathematical functions, this should improve performance.

It's the most important new feature updates in PHP 8, JIT is not enabled by default. However JIT doesn't make that much of a difference on web applications.

Example about JIT performance demonstrated:

Ref Source: PHP 8 - New Features, Improvements and Potential Problems with WordPress

2. PHP 8 New features

===
Thanks to:

The nullsafe operator RFC

Instead of writing classic !== null you can use the “?” operator to write just 1 line of code, the application application becomes pretty clear:

Before:



$country =  null;

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

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

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


Enter fullscreen mode Exit fullscreen mode

After:



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


Enter fullscreen mode Exit fullscreen mode

Constructor property promotion

Instead of specifying class properties and a constructor for them, PHP can now combine them into one.



// In php 7.x
class Point {
    protected float $x;
    protected float $y;
    protected float $z;

    public function __construct(
        float $x = 0.0,
        float $y = 0.0,
        float $z = 0.0,
    ) {
        $this->x = $x;
        $this->y = $y;
        $this->z = $z;
    }
}

// In PHP 8
class Point {
    public function __construct(
        protected float $x = 0.0,
        protected float $y = 0.0,
        protected float $z = 0.0,
    ) {}
}


Enter fullscreen mode Exit fullscreen mode

Union Types 2.0 RFC

PHP is a dynamically typed structure, So union types are very useful in a lot of places. Union types are a collection of two or more types which indicate that either one of those can be used.



// In PHP 7.4
class Number {
    private $number;

    public function setNumber($number) {
        $this->number = $number;
    }
}

// In PHP 8
class Number {
    private int|float $number;

    public function setNumber(int|float $number): void {
        $this->number = $number;
    }
}


Enter fullscreen mode Exit fullscreen mode

Mixed Type RFC

Reference link

Mixed type is a good addition to php8 type system. It is equivalent to one of these types.



  array|bool|callable|int|float|null|object|resource|string


Enter fullscreen mode Exit fullscreen mode

Here is an example from the RFC documentation of how this is used:



public function foo(mixed $value) {}


Enter fullscreen mode Exit fullscreen mode

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 mixed type.
function bar(): ?mixed {}


Enter fullscreen mode Exit fullscreen mode

Match Expression RFC

Does match expression replace the switch?. The match can return values, doesn't require lengthy statements like a switch. It uses strict type comparison



//The switch statement loosely compares (==) the given value to the case values. This can lead to some very surprising results.
switch ('100') {
  case 100:
    $price = "Oh no!";
    break;
  case '100':
    $price = "This is what I expected";
    break;
}
echo $price;
///> Oh no!

//The match expression uses strict comparison (===) instead. The comparison is strict regardless of strict_types.
echo match ('100') {
  100 => "Oh no!",
  '100' => "This is what I expected",
};


Enter fullscreen mode Exit fullscreen mode

Named Arguments RFC

Named arguments give you more flexibility when calling functions. Previously, you had to call a function and pass each argument in the order in which the function specified.



class ExampleClass {

  public function __construct(
      private string $title, 
      private string|null $description, 
      private string $type ) {

  }
}

// In  PHP 7.x
$my_class = new Log (
  'New Support request',
  '',
  'support',
);

// In PHP 8
$my_class = new ExampleClass (
  title : 'New Support request',
  description : 'You received a new support ...',
  type: 'support',
);

// even you can write something like these
$my_class = new ExampleClass (
  title : 'New Support request',
  type: 'support',
);


Enter fullscreen mode Exit fullscreen mode

Attributes

Instead of PHPDoc annotations, you can now use structured metadata with PHP's native syntax.



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

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


Enter fullscreen mode Exit fullscreen mode

PHP New Functions & Classes

New Classes, Interfaces, and Functions

  • Attributes v2 RFC.
  • Weak Maps RFC.
  • Throw Expression RFC.
  • Trailing Comma in Parameter List. ```php

class Comment {
public function __construct(
string $titla,
string $description,
int $status, // trailing comma
) {
// do something
}
}

- Inheritance with private methods [RFC](https://wiki.php.net/rfc/inheritance_private_methods).
- Arrays Starting With a Negative Index.
```php


$book = array_fill(-4, 6, 'title');
var_dump($book);
//output 
array(6) {
  [-4]=>
  string(5) "title"
  [-3]=>
  string(5) "title"
  [-2]=>
  string(5) "title"
  [-1]=>
  string(5) "title"
  [0]=>
  string(5) "title"
  [1]=>
  string(5) "title"
}

// In PHP 7.4 like these
//output 
array(6) {
  [-4]=>
  string(5) "title"
  [0]=>
  string(5) "title"
  [1]=>
  string(5) "title"
  [2]=>
  string(5) "title"
  [3]=>
  string(5) "title"
  [4]=>
  string(5) "title"
}
=> null


Enter fullscreen mode Exit fullscreen mode
  • Non-capturing catches RFC ```php

//Before PHP 8
try {
AddUser();
} catch (PermissionException $ex) {
echo "You don't have permission to add user";
}

//PHP 8
try {
AddUser();
} catch (PermissionException) { //The intention is clear: exception details are irrelevant
echo "You don't have permission to add user";
}

- ...

### 3. PHP 8 impact & compatibility (with Wordpress).
===
[Reference Link](https://developer.yoast.com/blog/the-2020-wordpress-and-php-8-compatibility-report/)

[Wordpress Version Compatibility](https://make.wordpress.org/core/handbook/references/php-compatibility-and-wordpress-versions/)

PHP 8 is a major update of PHP and WordPress aims to always be compatible with new versions of PHP.

Only a small percentage of the available plugins, the more popular and professionally developed ones, have automated tests in place.

PHP 7.* versions have seen a far larger set of deprecations than previous versions of PHP. Where PHP 5.6 to PHP 7 was a relatively simple migration, going from 7.x to 8 could be very painful, especially for very old codebases, the reality, however, is that WordPress is not such a codebase.

#### The test report is:

** Issues reported early on in the WP 5.6 dev cycle and fixed since based on PHPCompatibility scans:

- [Optional parameters declared before required parameters](https://core.trac.wordpress.org/ticket/50343)
- [Final private methods](https://core.trac.wordpress.org/ticket/50897)
- [Remove use of create_function](https://core.trac.wordpress.org/ticket/50899)
- [Only call libxmldisableentity_loader conditionally](https://core.trac.wordpress.org/ticket/50898)


** There are a large number of PHP warnings that have been changed to error exceptions in PHP 8. 

** Error level changes unrelated to RFC’s
The following warnings have been converted to errors probably related to deprecations in PHP 7.x versions:

- Attempting to write to a property of a non-object. Previously this implicitly created an stdClass object for null, false and empty strings.
- Attempting to append an element to an array for which the PHP_INT_MAX key is already used.
- Attempting to use an invalid type (array or object) as an array key or string offset.
- Attempting to write to an array index of a scalar value.
- Attempting to unpack a non-array/Traversable.

** Warnings coming from anywhere

PHP 8 is going to contain a lot of breaking changes and focusing so strongly on strict typing, WordPress’ type unsafe extensibility system also becomes extra vulnerable to errors, potentially leading to plugins causing type errors in other plugins or WordPress itself, many warnings that will turn into errors with PHP 8.

### 4. Deprecated

During the PHP 7.x release cycle, each version introduced new deprecations, which have now been finalized as feature removals in PHP 8. This also applies to some deprecation which were already put in place in PHP 5.x, but weren't removed in the PHP 7.0 release.

- php_errormsg.
- create_function().
- mbstring.func_overload.
- parse_str() without second argument.
- each().
- assert() with string argument.
- $errcontext argument of error handler.
- String search functions with integer needle.
- Defining a free-standing assert() function.
- The real type (alias for float).
- Magic quotes legacy.
- array_key_exists() with objects.
- Reflection export() methods.
- implode() parameter order mix.
- Unbinding $this from non-static closures.
- restore_include_path() function.
- allow_url_include ini directive.
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
rsvp profile image
Аqua 🜉іtæ ℠

thx 2 ya. Pls, provide a link 4 "Named Arguments" & #[Route("/api/posts/{id}", methods: ["GET"])]' @ php.net. As well can u elaborate further JIT vs Docker?

Collapse
 
adarsh_bankopen profile image
adarsh-bankopen

Can someone elaborate the following:

Unbinding $this from non-static closures.