Search code examples
phpphp-7type-hinting

What is the purpose of the question marks before type declaration in PHP7 (?string or ?int)?


Could you please tell me how is this called? ?string and string

Usage example:

public function (?string $parameter1, string $parameter2) {}

I wanted to learn something about them but I cannot find them in PHP documentation nor in google. What is difference between them?


Solution

  • What is a Nullable Type?

    Introduced in PHP 7.1,

    Type declarations for parameters and return values can now be marked as nullable by prefixing the type name with a question mark. This signifies that as well as the specified type, NULL can be passed as an argument, or returned as a value, respectively.

    In parameters

    function test(?string $parameter1, string $parameter2) {
        var_dump($parameter1, $parameter2);
    }
    
    test("foo", "bar");
    test(null, "foo");
    test("foo", null); // Uncaught TypeError: Argument 2 passed to test() must be of the type string, null given,
    

    With variadic arguments

    In this example, you can pass null or string parameters :

    function acceptOnlyStrings(string ...$parameters) { }
    function acceptStringsAndNull(?string ...$parameters) { }
    
    acceptOnlyStrings('foo', null, 'baz'); // Uncaught TypeError: Argument #2 must be of type string, null given
    acceptStringsAndNull('foo', null, 'baz'); // OK
    

    Return type

    The return type of a function can also be a nullable type, and allows to return null or the specified type.

    function error_func(): int {
        return null ; // Uncaught TypeError: Return value must be of the type integer
    }
    
    function valid_func(): ?int {
        return null ; // OK
    }
    
    function valid_int_func(): ?int {
        return 2 ; // OK
    }
    

    Property type (as of PHP 7.4)

    The type of a property can be a nullable type.

    class Foo
    {
        private object $foo = null; // ERROR : cannot be null
        private ?object $bar = null; // OK : can be null (nullable type)
        private object $baz; // OK : uninitialized value
    }
    

    See also :

    Nullable union types (as of PHP 8.0)

    As of PHP 8, "?T notation is considered a shorthand for the common case of T|null"

    class Foo
    {
        private ?object $bar = null; // as of PHP 7.1+
        private object|null $baz = null; // as of PHP 8.0
    }
    

    Error

    In case of the running PHP version is lower than PHP 7.1, a syntax error is thrown:

    syntax error, unexpected '?', expecting variable (T_VARIABLE)

    The ? operator should be removed.

    PHP 7.1+

    function foo(?int $value) { }
    

    PHP 7.0 or lower

    /** 
     * @var int|null 
     */
    function foo($value) { }
    

    References

    As of PHP 7.1: Nullable type :

    As of PHP 7.4: Class properties type declarations.

    As of PHP 8.0: Nullable Union Type