What to expect in the next generation of Laravel Forge. Read the blog post
Rewatch this lesson

Next video in… 10

Composer

Modern PHP

PHP Fundamentals

Modern PHP
Explore PHP's modern features like constructor property promotion, match expressions, and nullsafe operators.


PHP has evolved significantly in recent years. Let's look at some modern features that make PHP code cleaner, safer, and more enjoyable to write. These features are especially relevant when working with frameworks like Laravel.

Performance Improvements

PHP 8 brought significant performance improvements through various optimizations in its core engine. Modern PHP applications run noticeably faster, making PHP a strong choice for web development in 2025.

Constructor Property Promotion (PHP 8.0)

One of the most welcome improvements in modern PHP is constructor property promotion. It eliminates the boilerplate code of declaring properties and then assigning them in the constructor. This is particularly useful for data objects and simple classes:

1// Old way
2class User {
3 public string $name;
4 public string $email;
5 
6 public function __construct(string $name, string $email) {
7 $this->name = $name;
8 $this->email = $email;
9 }
10 
11}
12 
13// Modern way
14class User {
15 public function __construct(
16 public string $name,
17 public string $email,
18 ) {}
19}

Readonly Properties (PHP 8.1)

Readonly properties add an extra layer of safety to your code. Once a property is set in the constructor, it cannot be changed. This is great for values that should remain constant throughout an object's lifetime, like IDs, dates of creation, or configuration values:

1class Price {
2 public function __construct(
3 public readonly float $amount,
4 public readonly string $currency
5 ) {}
6}

Match Expression (PHP 8.0)

The match expression is a modern replacement for the switch statement. It's more concise, returns values directly, and does strict comparisons by default. It's perfect for mapping values or handling different cases:

1// Old way with switch
2switch ($status) {
3 case 200:
4 $result = 'success';
5 break;
6 case 404:
7 $result = 'not found';
8 break;
9 case 500:
10 $result = 'server error';
11 break;
12 default:
13 $result = 'unknown status';
14}
15 
16// Modern way with match
17$result = match ($status) {
18 200 => 'success',
19 404 => 'not found',
20 500 => 'server error',
21 default => 'unknown status'
22};

Nullsafe Operator (PHP 8.0)

The nullsafe operator (?->) helps prevent null reference errors when accessing properties or methods in a chain. It's particularly useful when working with optional relationships or nested data structures:

1// Old way
2$country = null;
3 
4if ($user !== null) {
5 if ($user->getAddress() !== null) {
6 $country = $user->getAddress()->getCountry();
7 }
8}
9 
10// Modern way
11$country = $user?->getAddress()?->getCountry();

Named Arguments (PHP 8.0)

Named arguments make function and method calls more explicit and self-documenting. They're especially useful when dealing with multiple optional parameters or when the parameter names are important for understanding:

1$user = new User("John", "[[email protected]](<mailto:[email protected]>)");
2 
3// Works the same
4$user = new User(
5 name: "John",
6 email: "[[email protected]](<mailto:[email protected]>)"
7);

Typed Properties (PHP 7.4)

Type declarations for properties help catch errors early and make code more reliable. PHP will ensure that only values of the correct type can be assigned to these properties:

1class User {
2 public string $name;
3 public int $age;
4 public ?string $email = null; // Nullable string
5}

These modern features make PHP code:

  • More concise and expressive

  • Safer with better type checking

  • Easier to read and maintain

  • Less prone to errors

00:00
PHP has evolved significantly in recent years, so let's take a look at some modern features
00:05
that make PHP code cleaner, safer, and more enjoyable to write.
00:10
These features are especially relevant when working with frameworks like Lervo.
00:15
So here's a user class very similar to what we had already before with our product class.
00:20
We're defining here the properties and then we have a constructor where we receive data
00:24
from the outside and then we assign it to our properties.
00:27
But I've already shown you that there is a nicer way to write this and this is possible
00:31
since constructor property promotion, which we have in PHP since version 8.0.
00:38
So what we're doing here is we are getting rid of the assignment of the properties here
00:43
and we're doing all of this in the constructor.
00:46
So we're just adding here full, the access level, the type, and the name.
00:51
And the same public string email.
00:55
And now we have defined those here and then we also don't need to assign them anymore.
01:00
This now works automatically, just defining them here in the constructor.
01:05
And yeah, this is now so much cleaner than before and this is such a cool feature.
01:10
I really love this one.
01:13
And since we're already here, another one is we also have read-only properties.
01:18
So you can define a property public read-only string name in this case.
01:23
So this is now read-only.
01:25
So if we create a new user with a name and an email, and let's just echo out the user's
01:33
email, you can see this works.
01:36
It also works for the name.
01:39
Here we go.
01:40
But something which we can also do, I think we haven't covered this yet, but you can also
01:44
change public values.
01:46
So let's say the name is now Taylor and not Christoph anymore.
01:51
And if we try to do this, maybe let's start here with the email.
01:56
Doesn't matter that it's not a name, it's still working.
01:58
But if we try to do this now on the name, you will see this will fail because we cannot
02:03
modify read-only properties.
02:05
And that's exactly what we're trying to do here.
02:07
We have a read-only property.
02:09
We want this to be only readable and not to get overridden like we do here.
02:15
So very cool feature as well.
02:17
Change this back to the email where we can change stuff.
02:20
You can see it's working if we try to override this one.
02:24
So not a very cool feature, which we have in PHP since version 8.1.
02:28
Okay, something else.
02:30
Let me bring in here another example.
02:33
So here we have a switch expression.
02:35
So we haven't talked about this yet, but this is possible in PHP.
02:39
So let's imagine you have a status, which comes from somewhere else.
02:44
Let's just say this is 200.
02:46
And then inside the switch here, expression here, we're checking what is the value of
02:51
the status.
02:52
And then we have different cases.
02:53
So if the value is 200, then we're going to assign this string here to this variable.
02:58
If 204, it's this string and so on.
03:01
If it's something else, then we have this default value.
03:04
In this case, let's echo out what we now got with the result here and should be success.
03:10
And it is.
03:11
And of course, if we change this now to something else, which we haven't defined, where we don't
03:15
have a case for this, and now this is being matched and we get this string.
03:20
By the way, we also have those breaks in between to end every case.
03:25
And yet this has been in PHP for a very long time.
03:29
Nothing bad about this, but yet there is now a little bit nicer way in order to deal with
03:34
those examples.
03:35
So what we can do now is we now have a new match operator, match expression.
03:42
Where we can directly get the result.
03:45
So first, this is the same, we're receiving one value, which in this case is status.
03:50
And then we don't have cases anymore.
03:53
We have a value.
03:54
And if this is match, we assign with this error operator here, specific value here.
04:01
And we also don't need to assign the variable here because we have this already at the beginning.
04:05
So the only thing we need is something like this.
04:10
Let me get this changed for the other cases as well.
04:14
And now it looks like this.
04:15
So you can see this is already way cleaner than before.
04:18
Way less code.
04:19
You can already see this is what we're looking for.
04:21
This is what we're returning.
04:23
No variable assigning here in every case.
04:26
We do this at the beginning.
04:27
And yeah, this is just so cool.
04:29
And if we run this, you can see this is still working.
04:32
Let's try out 200 again and we get success back as it should be.
04:37
So take a look at the match expression.
04:38
It's very powerful and very clean to use in your PHP applications.
04:43
Okay, here we go.
04:45
Our next example.
04:46
We have two classes here.
04:48
One is for the address where we have a method here to get a country.
04:52
This case it's Austria.
04:54
And here we have an order.
04:56
And here we can get the address of a specific order.
05:01
And then we are here creating a new order.
05:03
So what we're going to do, we want to get the country of the order.
05:08
And the way that we would do this is by using the order, then get the address.
05:13
And then we can chain calls normally would get here back an instance of the address.
05:18
So this means we should also be able to get the country directly.
05:22
This is how we would get our country.
05:25
But this is failing now because we're calling a member function, get country on null.
05:31
So this means we're trying to run this method, get country on something that here is null.
05:37
And this is failing because yeah, this doesn't work like that in PHP.
05:42
But usually if we would return here a real address, this code would work.
05:46
But we also have to encounter situations where this order doesn't have an address yet.
05:51
And one way to do this is we could say the country is null.
05:56
And then we're checking if order get address.
05:59
So if this is available, let's gather this up here.
06:07
And only if this is the case, then we want to change the country.
06:10
And then we're going to reuse this again, order, get address, get country.
06:18
So what you can see now is we don't have any errors anymore if we run this.
06:22
And if we var dump out our country, you will see the value is now null.
06:29
And by the way, we haven't talked about what null means.
06:31
It's a data type in PHP, which just means there is no value.
06:35
So it's different from something being set to false, zero, an empty string, because these
06:39
are all values.
06:41
But null just means there is no value set.
06:44
And that's exactly what we have defined here.
06:46
And since this condition is not being matched, because we get null back here, it jumps directly
06:51
here and dumps out the country, which is still null.
06:56
So this is one way you could overcome the issue if this method returns something which
07:02
is null, which is the case in our example here.
07:05
But of course, these if conditions are not very readable.
07:09
And if you have to write them a lot, this is not so much fun.
07:12
So we can do something different now.
07:14
So what we're doing now, we're now trying the same.
07:17
We're going for the order.
07:20
And then we're using get address.
07:22
But then we are assigning here a null operator, which we're defining here with this question
07:27
mark.
07:28
And only if this is not null, if this is not null, so this is what this means, then we're
07:33
going to go for get country.
07:36
And this code should now still work.
07:38
Yes, we get null back, so exactly what we do.
07:41
But still, it would also work if we get an address here, but it also works if we don't
07:45
get.
07:46
And yeah, this is how we can change this if we would have, if this would give us back
07:50
another instance, we could run another operator again with this on it if we want to.
07:56
But yeah, that's basically the null safe operator, which was introduced in PHP 8.0.
08:02
And it just makes sure that it's not throwing an error here.
08:06
If this is null, it just returns null, because that's what we're saying here.
08:11
Hey, if this is not given, if this is not what it should be, then just return null and
08:17
don't move on anymore with what's coming after this.
08:21
So give this a look and play a little bit around with the null safe operator, because
08:25
this is something that you will use quite regularly.
08:28
And it's a pretty cool feature to make your code way cleaner and more readable.
08:33
All right, let's get rid of this.
08:36
So I'm bringing back here the product example, which we already had before.
08:40
Let's create a new product together.
08:42
Let's say this is a new product, and I'm going to provide a name.
08:46
Let's go for laptop again, and it costs $100 in this case.
08:52
All right, so this is working.
08:54
And the way that, again, it works, we're providing two parameters here.
08:58
And the first one is the name, and the second one is the price.
09:02
And for us in this case, it's obvious that this is the name, and this is the price.
09:08
But there might be situations where you have a lot of properties, and some of them are
09:12
being set to be optional.
09:14
Like we could set them to null, and we also need to define.
09:17
You can also do this with question mark, saying that this should be a float, but it could
09:22
also be null, which is sometimes very helpful, because it could be that this is just not
09:26
defined, and you don't need it every time.
09:29
But when it's there, it should be a float, but when it's not there, it can be just null.
09:33
So that's what we're seeing here.
09:34
And let's create a couple of these here.
09:37
So let's say maybe that's the before price, and this is the after price, something like
09:43
that.
09:44
And all of these are optional.
09:47
And if you now want to define what the after price is, the way that this would work now,
09:52
let's give us a little bit more space here.
09:57
So we're first defining that laptop is the name, and the price.
10:02
In this case, let's say we don't want to define it, but we want to define the after price.
10:07
So what we now have to do is we want to say that this is null.
10:11
All right.
10:12
Then the before price, the next one should also be null.
10:15
And then the after price, we're going to set to 100.
10:18
Let's make sure this works.
10:20
Yes.
10:21
Okay.
10:22
This does.
10:23
So yeah, this is now a little bit strange because you have to define all those optional
10:27
values just in order to also define this last one here, which is a little bit cumbersome
10:32
and not that readable and nice to use.
10:35
So that's why we now have a way better way to do this with named arguments in PHP 8.0.
10:42
And the way this works, we can define the name of the property before the value.
10:46
So this is for the name, then this is for the price, colon.
10:50
This is the before price, and this is the after price.
10:55
Let's try this out.
10:56
Yeah, you can see this is still working.
10:58
And for now, it just looks like we have more code than before.
11:01
And yeah, it's the case.
11:02
But the good thing about this is we can now get rid of the optional ones because we don't
11:07
need to define them anymore.
11:09
Let's get rid of this.
11:10
Let's try to run this.
11:11
And you can see this is now still working.
11:13
We're just defining here the first argument and the last one.
11:17
And this now works by defining those named arguments here or using those named arguments
11:22
here to tell PHP exactly what those values are for.
11:26
And yet it's especially useful if you first want to make clear what those value mean,
11:32
because now it's readable.
11:33
Okay, this is the name and this is the after price.
11:35
Because if we don't have this, it would be quite difficult to see what this means if
11:39
you don't have this class open.
11:42
So this means for readability could be one reason to use them.
11:45
And the second one is to define the order in how you want to assign those values and
11:51
that you don't need to define the one which are default and which you don't want to change
11:56
here through the constructor.
11:58
So yeah, named arguments also very, very cool feature in PHP, which I've already been using
12:04
a lot in my projects.
12:06
And we at Laravel use this a lot too.
12:11
And then lastly, also something which is new, which we see here are those types here, which
12:15
we can define for our arguments here for this class.
12:19
So type properties is something which we have in PHP since 7.4.
12:23
So we didn't have this before, so you could just provide anything in here.
12:27
But yeah, now with the types, we can be very specific about what type this value should
12:33
be.
12:34
And this is something that good developers use all the time because this is very helpful
12:38
and gives a lot of strictness to your code, which helps to prevent a lot of bugs.
12:45
So yeah, these were some of the new features which we have in PHP and what makes PHP more
12:50
joy to write, safer and gives us cleaner code.
12:53
And there's much more coming.
12:55
The ecosystem and PHP itself is very active.
12:58
And here we get a lot of very cool features now with every release, which is really cool.