Many programming languages allow some sort of optional or nullable types, depending on terminology. The PHP dynamic type already supports this notion via the built-in null type. A variable is considered to be of the null type if it has been assigned a constant value null, it has not been assigned any value, or it has been unset using the unset() construct. Aside from variables, the null type can also be used against the function parameters, by assigning them a default value of null.
However, this imposed a certain limitation, as we could not declare a parameter that might be null without flagging it as optional at the same time.
PHP 7.1 addressed this limitation by adding a leading question mark symbol (?) to indicate that a type can be null, unless specifically assigned to some other value. This also means that type could be null and mandatory at the same type. These nullable types are now permitted pretty much anywhere where type declarations are permitted.
The following is an example of the nullable type with a mandatory parameter value:
function welcome(?string $name) {
echo $name;
}
welcome(); // invalid
welcome(null); // valid
The first call to the welcome function throws an \Error, because its declaration is making the parameter mandatory. Goes to say that the nullable type should not be mistaken with null being passed as a value.
The following is an example of a nullable type with an optional parameter value, optional in the sense that it has been assigned a default value of null already:
function goodbye(?string $name = null)
{
if (is_null($name))
{
echo 'Goodbye!';
}
else
{
echo "Goodbye $name!";
}
}
goodbye(); // valid
goodbye(null); // valid
goodbye('John'); // valid
The following is an example of function declaration using the nullable return type:
function welcome($name): ?string
{
return null; // valid
}
function welcome($name): ?string
{
return 'Welcome ' . $name; // valid
}
function welcome($name): ?string
{
return 33; // invalid
}
The nullable types work both with scalar types (Boolean, Integer, Float, String) and compound types (Array, Object, Callable).