DEV Community

Cover image for What's New in PHP 8.1?
The Dev Drawer
The Dev Drawer

Posted on

What's New in PHP 8.1?

If you are still using PHP 7 then this article is for you. There is some highly-requested functionality built into PHP 8, specifically PHP 8.1 that you need to know. It will make your programming life much easier.

View This On YouTube

In this article, I am going to show you the PHP 7 way, then I am going to show you the PHP 8 way. Let's cut to the chase.

NULLSafe Operators

If you've used the null coalescing operator in the past, you probably also noticed its shortcomings: null coalescing doesn't work on method calls.

The nullsafe operator provides functionality similar to null coalescing, but also supports method calls.

The NULLSafe Operator will allow you to check for nulls on a method so there is no need for an IF statement within the response itself. Instead you would simple add ? after the method to check it for a null return.

PHP 7

class User {
    public function getProfile() {
        return null;
        return new Profile;
    }
}

class Profile{
    public function getTitle() {
        return null;
        return "Software Engineer";
    }
}

$user = new User;
$profile = $user->getProfile();

/*
pre null coalescing
if ($profile) {
    if($profile->getTitle()) {
        echo $profile->getTitle();
    }else{
        echo 'Not provided';
    }
}
*/

/* post null coalescing */
echo ($profile ? ($profile->getTitle() ?? 'Not provided') : 'Not provided'); 

Enter fullscreen mode Exit fullscreen mode

PHP 8

class User {
    public function getProfile() {
        //return null;
        return new Profile;
    }
}

class Profile{
    public function getTitle() {
        //return null;
        return "Software Engineer";
    }
}

$user = new User;
$profile = $user->getProfile();

// uses NULL Operator after the getProfile() method
echo $user->getProfile()?->getTitle() ?? 'Not provided';
Enter fullscreen mode Exit fullscreen mode

Constructor Property Promotion

Property promotion allows you to combine class fields, constructor definition and variable assignments all into one syntax, in the construct parameter list.

Ditch all the class properties and the variable assignments, and prefix the constructor parameters with public, protected or private. PHP will take that new syntax, and transform it to normal syntax under the hood, before actually executing the code.

NOTE: Promoted properties can only be used in constructors.

PHP 7

class Signup {
    protected UserInfo $user;

    protected PLanInfo $plan;

    public function __construct(UserInfo $user, PlanInfo $plan) {
        $this->user = $user;
        $this->plan = $plan;
    }
}

class UserInfo {
    protected string $username;

    public function __construct($username) {
        $this->username = $username;
    }
}

class PlanInfo {
    protected string $name;

    public function __construct($name = 'yearly') {
        $this->name = $name;
    }
}

$userInfo = new UserInfo('Test Account');
$planInfo = new PlanInfo('monthly');

$signup = new Signup($userInfo, $planInfo);
Enter fullscreen mode Exit fullscreen mode

PHP 8

class Signup {
    public function __construct(protected UserInfo $user, protected PlanInfo $plan) {
    }
}

class UserInfo {
    public function __construct(protected string $username) {
    }
}

class PlanInfo {
    public function __construct(protected string $name = 'yearly') {
    }
}

$userInfo = new UserInfo('Test Account');
$planInfo = new PlanInfo('monthly');

$signup = new Signup($userInfo, $planInfo);
Enter fullscreen mode Exit fullscreen mode

Match Expressions

PHP 8 introduces the new match expression. A powerful feature that will often be the better choice to using switch.

NOTE: Match will do strict type checks instead of loose ones. It's like using === instead of ==.

PHP 7

$test = 'Send';

switch ($test) {
    case 'Send':
        $type = 'send_message';
        break;
    case 'Remove':
        $type = 'remove_message';
        break;
}
echo $type;
Enter fullscreen mode Exit fullscreen mode

PHP 8

$test = 'Send';

$type = match ($test) {
    'Send'=>'send_message',
    'Remove'=>'remove_message'
};

echo $type;
Enter fullscreen mode Exit fullscreen mode

$object::class

It is now possible to fetch the class name of an object using $object::class. The result is the same as get_class($object).

If you working on php long enough I believe you have tried doing class syntax like this Class::method or get_class(new Class()) to fetch a class name as a string. However, if you assign a dynamic class name into a variable and use class syntax like this $object::class you will get an error "Cannot use ::class with dynamic class name". In PHP 8, you can.

PHP 7
N/A, shows error

PHP 8

class Send{}
$message = new Send();

$type = match ($message::class) {
    'Send'=>'send_message',
    'Remove'=>'remove_message'
};
Enter fullscreen mode Exit fullscreen mode

Named Parameters/Arguments

Named arguments allow you to pass input data into a function, based on their argument name instead of the argument order. This type of functionality is good for keeping tracking of what means what. If you go back to your code and see where you are a calling a method, you may get confused as to what you are calling.

Named parameters help prevent this. They give you the ability to tell your future self what type of variables you are assigning to the method without having to dig through your code and figure out what it does.

NOTE: If your argument names change in the method, it will break your code as the named parameter is no longer valid.

PHP 7

class Invoice {
    private $customer;
    private $amount;
    private $date;

    public function __construct($customer, $amount, $date) {
        $this->customer = $customer;
        $this->amount = $amount;
        $this->date = $date;
    }
}

$invoice = new Invoice(
    'Test Account', 
    100, 
    new DateTime
);
Enter fullscreen mode Exit fullscreen mode

PHP 8

class Invoice {
    public function __construct(private string $customer, private int $amount, private dateTime $date) {}
}

$invoice = new Invoice(
    customer: 'Test Account', 
    amount: 100, 
    date: new DateTime
);
Enter fullscreen mode Exit fullscreen mode

String Helpers

Have you ever wanted to find a string in a string in PHP? Most likely you have and most likely you know it is a pain since prior to PHP 8, there was not a lookup function for this purpose even thouh it is one of the most request items for PHP since it was created.

In the past, you need to understand how the math worked and match certain parameters, well, that is now gone and the future of string matching is here.

PHP 7

$string = 'inv_1234_mid_67890_rec';
echo 'Starts with inv_: '.(substr_compare($string, 'inv_', 0, strLen('_inc')) === 0 ? "Yes" : "No");
echo 'Ends with _rec: '.(substr_compare($string, '_rec', -strLen('_rec')) === 0 ? "Yes" : "No");
echo 'Contains _mid_: '.(strpos($string, '_mid_') ? "Yes" : "No");

Enter fullscreen mode Exit fullscreen mode

PHP 8

$string = 'inv_1234_mid_67890_rec';
echo 'Starts with inv_: '.(str_starts_with($string, 'inv_') ? "Yes" : "No");
echo 'Ends with _rec: '.(str_ends_with($string, '_rec') ? "Yes" : "No");
echo 'Contains _mid_: '.(str_contains($string, '_mid_') ? "Yes" : "No");
Enter fullscreen mode Exit fullscreen mode

Union and Pseudo Types

In versions prior to PHP 8.0, you could only declare a single type for properties, parameters, and return types. PHP 7.1 and newer versions have nullable types, which means you can declare the type to be null with a type declaration similar to ?string or by using PHPDoc comments.

From PHP 8.0, you can declare more than one type for arguments, return types, and class properties.

PHP 7

class Foo {

    public function bar(?Foo $foo) {
        echo 'Complete';
    }
}

$one = new Foo;
$two = new Foo;

$two->bar($one);
$two->bar(null);
// string fails as it is expecting Foo or Null
$two->bar('Test');
Enter fullscreen mode Exit fullscreen mode

PHP 8

class Foo {

    public function bar(Foo|string|null $foo) {
        echo 'Complete';
    }
}

$one = new Foo;
$two = new Foo;

// everything works
$two->bar($one);
$two->bar(null);
$two->bar('Test');
Enter fullscreen mode Exit fullscreen mode

Conclusion

What is your favorite new feature in PHP 8 and PHP 8.1? Mine is the string helpers and match functions because I already use the older version in almost every project I create in PHP. I hope this helps you make the switch to PHP 8.

Discussion (4)

Collapse
fabyo0 profile image
fabyo0

Hi
PHP 7.4.3 version is installed, do you think I should upgrade to php 8 version, will I have problems on the server or while developing a project?

Collapse
thedevdrawer profile image
The Dev Drawer Author • Edited on

I currently have 7.4+ installed on one of my local servers as well so it is not too much of a jump to PHP 8. However, it depends on how your code was written. There may be some functionality that does not work from PHP 7 to PHP 8, but I would assume most would.

If you are not sure of compatibility, I would recommend on running a staging server that has PHP 8 on it prior to moving a production server. This way you can test your current code base against any changes that may have occured.

Take a look at this migration guide:
php.net/manual/en/migration80.php

Note the deprecated and incompatible changes to see to see if you need to make any adjustments prior to switching.

Collapse
fabyo0 profile image
fabyo0

Thanks, I didn't have any problems with compatibility. I upgraded to php 8 version

Thread Thread
thedevdrawer profile image
The Dev Drawer Author

That is great. I hope you like 8 as much as I do.