Advantages of migrating to PHP 8

Posted on

New features of PHP 8 with examples of implementation and use

Hello!
It is a post prepared by the Hostman team. Our hosting platform deploys and scales web apps, so you can launch your apps in just a few clicks using a friendly interface.



Introduction



Announcement of a new version of PHP

PHP 8, a new major version, was released on November 26, 2020. The added features have been selected and discussed by the community for a long time. This post is a brief review of its features and improvements and a guide how to use them in practice.



Union type

Union types allow to specify a list of possible types for a value. If a value of the same type is passed, the type will be retained. If the type is not in the list and the strict types mode is not set, then an attempt will be made to convert it to a similar type (for example, float is converted to int). If the conversion is impossible, an exception of TypeError will be thrown. If the strict types mode is enabled, the type conversion will fail.

<?php

class TestUnion
{
    public function func(int|string $a): void
    {
        var_dump($a);
    }
}

$tu = new TestUnion();
$tu->func(1); // Output int(1)
$tu->func('1'); // Output string(1) "1"
$tu->func(1.5); // Output int(1)
$tu->func(new TestUnion()); // Fatal error
Enter fullscreen mode

Exit fullscreen mode

<?php

declare(strict_types=1);

class TestUnion
{
    public function func(int|string $a): void
    {
        var_dump($a);
    }
}

$tu = new TestUnion();
$tu->func(1); // Output int(1)
$tu->func('1'); // Output string(1) "1"
$tu->func(1.5);  // Fatal error
$tu->func(new TestUnion());  // Fatal error
Enter fullscreen mode

Exit fullscreen mode



Mixed type

The new type mixed allows to set any available type for a function or a method of a class argument. In fact, it is a typing bypass that allows backward compatibility with legacy code.

<?php

class TestMixed
{
    public function func(mixed $a): void
    {
        var_dump($a);
    }
}

$tu = new TestMixed();
$tu->func(1); // Output int(1)
$tu->func('1'); // Output string(1) "1"
$tu->func(1.5); // Output float(1.5)
$tu->func(new TestMixed()); // Output object(TestMixed)#2 (0) {}
Enter fullscreen mode

Exit fullscreen mode



WeakMap class

WeakMap is a key-value store where the key is an object and the value can be of any type. If a key object is deleted by the garbage collector, this key will be automatically deleted from the store.

<?php

declare(strict_types=1);

class Test {}

$test1 = new Test();
$test2 = new Test();

$map = new WeakMap();

$map[$test1] = 10;
$map[$test2] = 20;

var_dump($map[$test1]);
var_dump($map[$test2]);

var_dump($map);
unset($test2);
var_dump($map);
Enter fullscreen mode

Exit fullscreen mode

Output:

int(10)
int(20)
object(WeakMap)#3 (2) {
  [0]=>
  array(2) { 
    ["key"]=> object(Test)#1 (0) {  }
    ["value"]=> int(10)
  }
  [1]=>
  array(2) {
    ["key"]=> object(Test)#2 (0) {  }
    ["value"]=>  int(20)
  }
}
object(WeakMap)#3 (1) {
  [0]=>
  array(2) {
    ["key"]=> object(Test)#1 (0) {  }
    ["value"]=>  int(10)
  }
}
Enter fullscreen mode

Exit fullscreen mode



Exception Type: ValueError

The new exception type ValueError is used when an invalid argument value is passed to a function, only if the type is correct.

<?php

declare(strict_types=1);

try {
    json_decode('{}', true, -1);
} catch (ValueError $e) {
    echo $e::class; // Output ValueError
}
Enter fullscreen mode

Exit fullscreen mode



Variadic arguments

From now on, when inheriting in an overridden method, you can specify a variadic argument instead of the old set of arguments.

<?php

declare(strict_types=1);

class A {
    public function method(int $arg1, int $arg2, int $arg3)
    {
    }
}

class B extends A {
    public function method(...$allArgs) 
    {
        var_dump($allArgs);
    }
}

$b = new B();
//  array(3) { [0]=> int(0) [1]=>  int(1) [2]=> int(2}
$b->method(0, 1, 2);
Enter fullscreen mode

Exit fullscreen mode



Static return type

The static keyword can be specified as the return type of the method. Unlike the return type self, this method can return child objects.

It is convenient to use this feature for extending the functionality of a class by inheritance, when a method of the parent class returns its instance.

<?php

declare(strict_types=1);

class TestStatic
{
    public function func(): static
    {
        return $this;
    }
}

class A extends TestStatic
{
    public function func2(): static
    {
        return $this;
    }
}

$ts = new TestStatic();
$a = new A();

echo $ts->func()::class; // Output TestStatic
echo $a->func()::class; // Output A
echo $a->func2()::class; // Output A
Enter fullscreen mode

Exit fullscreen mode



Class keyword on an object instance

In the new version you can use the $object::class constant to get the class that owns an object instance. Please note that when this feature is used on an instance of the current class $this, we obtain the class that was instantiated.

<?php

declare(strict_types=1);

class TestClass
{
    public function func(): static
    {
        return $this;
    }
}

$tc = new TestClass();

echo $tc::class; // Output TestClass
echo $tc->func()::class; // Output TestClass

Leave a Reply

Your email address will not be published. Required fields are marked *