Type hinting in PHP – at long last!

This entry was posted by on Tuesday, 1 August, 2017 at

PHP has always been a “messy” language. It’s API looks somewhat thrown together by several different people who do not seem to be aware of each other’s existence, but surely have the best intentions. Given these ‘tools’, it comes as little surprise that writing good PHP code used to be more of an art than science. If the language does not force consistency, then it requires a great deal from the developer.

Luckily, with PHP 7.0 and 7.1 came the awesome feature of type hinting:


function fooBar(int $nuppi, ?float $baz): int {
// do something useful
return $numberOfNuppis;
}

This greatly improves the ability to program by contract in PHP and helps to clearly set interfaces: I can call function fooBar, but am supposed to pass an int ($nuppi) and a float $baz, which may also be null. In return, it will give me an int value.

Why is this great?

* Before 7.0, it was not certain how this function was supposed to be called. Of course you should use the @param/@return phpDoc, but this did nothing at runtime – it was still possible to do fooBar(‘gurp’, 5).

* Correct use of a function had to be apparent from its context – if fooBar() is called elsewhere with an int as an argument, then that is probably the way to go. But the fact that null, ”, ‘0’, 0, 0.0 and [] all evaluate to boolean false makes it difficult to reliably work with booleans this way.

* If you wanted to enforce any kind of check, you’d have to go about throwing a lot of defensive measures inside the function:


if (!is_int($nuppi)) {
return;
}

This pollutes the code (clutters actual functionality, introduces bugs, requires maintenance, etc.) and also forces other code to deal with whatever we return – void, null, -1. It is difficult to make this consistent across an entire project with multiple developers.

* If you wanted to use a function that was not properly documented, it could throw an unspecified result – void, int, null, array of some type of objects. The return type now makes this explicit.

* For both the parameters and the return value, you don’t have to do the checking anymore – PHP does that for you now, and will throw a TypeError if the function violates its contract.

The result? Better code because the language helps you do it right!

Comments are closed.