I've been experimenting with type-hinting in PHP and came across something when doing some tests. I have this function:
function foobar(string $foo)
{
return gettype($foo);
}
I have experimented with two uses:
echo foobar(4);
echo foobar('hello, world');
Both of these output string
. This instantly screams weird to me, because I pass an integer in my first use. I then, for kicks tried adding:
print_r(foobar(['hello']));
and sure enough I got the fatal error I was expecting with the first case use.
Taken from here it shows that int is different from a string:
+=======+==================================+
| int | The parameter must be an integer |
+=======+==================================+
|string | The parameter must be a string |
+=======+==================================+
So why does string $foo
allow my foobar(4)
and return string
?
As mentioned in the comments, PHP 7.0 introduced scalar type declarations and, in an effort to begin moving away from its messy loose typing, provided a "strict" mode. The default "coercive" mode lets PHP remain as loose as ever though.
When you specify the string type for the argument in coercive mode, you're telling PHP that you want the argument to be a string, and that it should try and make it a string if it's not.
By adding the declaration as the first line of your code, you can change the mode to get the desired behaviour:
<?php
declare(strict_types=1);
function foobar(string $foo)
{
return gettype($foo);
}
try {
echo foobar(4);
} catch (\TypeError $e) {
echo $e->getMessage();
}