PHP 8 New Features

Many new features have come to PHP over the years. With these new features, PHP has become a more powerful, modern, stable and faster language. In this post, I will explain the new features that come with PHP 8. PHP 8 version was released on 26 November 2020.

1- JIT Derleyici

The most notable innovation with PHP 8 is the JIT (just in time) compiler. PHP 8 offers two JIT compilation engines. Tracing JIT and Function JIT. Tracing JIT has a superior feature.

JIT was implemented as an almost independent part of OPcache. JIT working mechanism; the code is monitored and frequently used parts are compiled as bytcode and the compiled parts are executed at runtime.

PHP 8 performance metrics (kinsta.com)

Since JIT is part of OPcache, OPcache must be enabled. For this, we need to set opcache.enable=1 in php.ini file. Then we need to allocate memory like opcache.jit_buffer_size=1024M to enable JIT. Its default value is 0, so the JIT compiler is disabled. If you’re not sure if it’s enabled, you can check using the opcache_get_status function.

2- Union Types

With PHP 8, it allows multiple type definitions in variables, parameter declarations in functions, and function return type declarations.

class Product
{
    protected int|float $price; 
  
    public function setPrice(int|float $price): void 
    {
        $this->price = $price;
    }
    public function getPrice(): int|float 
    {
        return $this->price;
    }
}

3- Nullsafe Operator

With the null safe operator, we can more easily check with the null check ? operator in chain methods. If a method returns null, the process is stopped.

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

4- Match Expression

PHP 8 comes with a shorter and simpler structure of the switch case statement, the match statement. The result of the operation can be assigned to a variable or the returned value can be used.

/* PHP 8 */
switch (8.0) {
  case '8.0':
    $result = "Oh no!";
    break;
  case 8.0:
    $result = "This is what I expected";
    break;
}
echo $result; 
//OUTPUT: Oh no!
/* PHP 8 */
echo match (8.0) {
  '8.0' => "Oh no!",
  8.0 => "This is what I expected",
};
//OUTPUT: This is what I expected

5- Saner string to number comparisons

At PHP 8, if a numeric value is compared to string, the numeric value is converted to string and compared. PHP8 avoids inconsistencies such as PHP7 considering 0 as an empty string or the comparison of 123 == “123abc” returning true instead of false.

PHP7
0 == 'foobar' // true

PHP8
0 == 'foobar' // false

6- Named Arguments

We can specify mandatory parameters of a method or function and skip optional ones. For example, in a function that takes 9 parameters, the first 2 parameters are mandatory and the others are optional. If we want to send a value to only the 9th one of the optional parameters, we send the value to be sent to the function with its name.

In addition, if we define the parameters to be sent with their names, we can send them in the order we want.

function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);

7- Constructor property promotion

With PHP 8, it is easier to define and initialize properties inside the constructor method.

/*PHP 7*/
class Point {
  public float $x;
  public float $y;

  public function __construct(float $x = 0.0, float $y = 0.0) {
    $this->x = $x;
    $this->y = $y;
  }
}
/*PHP 8*/
class Point {
  public function __construct(
    public float $x = 0.0,
    public float $y = 0.0,
  ) {}
}

7- Attributes V2

A feature called annotation in Java, decorator in JavaScript and python and used to define metadata to classes, methods, functions, and variables is now available in PHP8.

<<ExampleAttribute>>
class Foo
{
	<<ExampleAttribute>>
	public const FOO = 'foo';

	<<ExampleAttribute>>
	public $x;

	<<ExampleAttribute>>
	public function foo(<<ExampleAttribute>> $bar) { }
}

$object = new <<ExampleAttribute>> class () { };

<<ExampleAttribute>>
function f1() { }

$f2 = <<ExampleAttribute>> function () { };

$f3 = <<ExampleAttribute>> fn () => 1;

8- Consistent type errors for internal functions

PHP built-in functions now give more consistent error messages.

/**PHP 7*/
strlen([]); // Warning: strlen() expects parameter 1 to be string, array given
/*PHP 8*/
strlen([]); // TypeError: strlen(): Argument #1 ($str) must be of type string, array given

9- Other Features

str_contains() : Checks whether a string expression contains another string expression. Returns a boolean value.

str_contains ( string $haystack , string $needle ) :
str_contains("PHP is awesome", "PHP") // Output : true 

str_starts_with() :Checks whether a string expression starts with another string expression. Returns a boolean value.


str_ends_with(): Checks if a string expression ends with another string expression. Returns a boolean value.


get_debug_type(): get_debug_type () does the same thing as gettype () we used before and returns us the type of the variable.

When the table below is examined, the differences between them will be understood more clearly.

TypeSample Valuegettypeget_debug_type
Integer123integerint
Float3.14doublefloat
Booleantruebooleanbool
Booleanfalsebooleanbool
String'Foo'stringstring
Array[1, 2, 3]arrayarray
NullnullNULLnull
Classnew Foo\Bar()objectFoo\Bar
Classnew DateTime()objectDateTime
Anonymous Classnew class {}objectclass@anonymous
Anonymous Classnew class extends Foo {}objectFoo@anonymous
Closurefunction() {}objectClosure
Streamtmpfile()resourceresource (stream)
Curlcurl_init()resourceresource (curl)
Xmlxml_parser_create()resourceresource (xml)

fdiv() : This function allows division by zero

fdiv(1, 0); // float(INF)
fdiv(-1, 0); // float(-INF)

mixed type : In PHP8, type definition of mixed type can be made and it replaces the following types.

array|bool|callable|int|float|null|object|resource|string
public function foo(mixed $value) {}

trailing commas in parameter lists: We can put a comma in the last parameter when defining a function.

public function foo(
		string $x,
		float $z, // trailing comma
	) {
		// do something
	}

using ::class on object : The use of get_class() before is now possible with $foo::class and gives the same result.

$foo = new Foo();

var_dump($foo::class);

Good Luck …