Php features: type hinting
Tags: php
Published: 2024-05-05 04:58:43

- [Attributes](https://dev.to/xwero/php-features-attributes-32p6)
- [First class callable syntax](https://dev.to/xwero/php-features-first-class-callable-syntax-5ab1)
- [Constructor changes](https://dev.to/xwero/php-features-constructor-changes-3ei5)
- [Parameter changes](https://dev.to/xwero/php-features-parameter-changes-3kni)

This post is going to be a mix of theory and code, because the code will be short. So lets dive in.

## Ancient history

Because my posts are about php 8.x versions, php 7.x versions feel so far away.

From php 7.0 you were able to set strict typing with `
declare(strict_types=1);`. And you were encouraged to use `===` and `!==` comparison operators to make sure the variables are of the same type.

With php 7.1 types where introduced that are not scalar types or custom classes. The nullable type, `function a(?string $b)`, was one of the most important because it was the beginning of having multiple types for one parameter.

Before php 7.4 you could only add type hinting to functions, from php 7.4 you can add type hinting to class properties.

## The php 8.x changes

The biggest change in php 8.0 are union types. This allows you to add multiple types per parameter. The nullable can now be `function a(string|null $b)`. This is more descriptive, and that is why i like it more.

Adjacent to the nullable type php 8.0 introduced the nullsafe operator, `$user->getAddress()?->street`. This reduces the null checks in your code. 
For the example code I would return an empty object instead of null, but there can be cases where null is the best choice.

Php 8.0 also introduced the mixed type. The idea is that if you want to allow more specific types in child class, you use mixed. The problem is that you can abuse the type if you have a code checker that forces you to use type hinting. 

Until now i only wrote about types that can be used as parameter and return type hinting, `function a(string $b): string { return $b; }`. But there are a few only return types. In php 7 there is `void`, php 8.0 added `static` and php 8.1 introduced `never`.
The difference between `void` and `never` is that the first signals that there is no return value. The second specifies that there is no return value and terminates the code or that the function is a part of an infinte loop. An example of an infinite loop is a function that redirects to another url.

Php 8.1 adds the posibility to intersect types. This means you can check multiple types per parameter. `function a(Traversable&ValueObject $b) {}`, in this example `$b` needs to implement both interfaces. 

In php 8.2 null can be used as a standalone type. Before null could only be used as a nullable type. Additionally `bool` can be split in `true` and `false`. The idea is to make the return type more specific. 

Php 8.2 also added disjunctive normal form types. It is a complex way to say you can now intersect and union types per parameter, `function a((Traversable&ValueObject)|null $b) {}`.

In php 8.3 you can type hint constants. So now are all parts of a class type hintable.

## Conclusion

For a dynamically typed language php added more and more typing to language. This improves your code because errors are found sooner than later.