php method argument type hinting with question mark (?type)

I just felt on pieces of php (symfony/laravel) code using question mark in method type hints :

public function functionName(?int $arg = 0)

In other occasions the ?type was not the last one, but I did not find any of these with no default yet.

Problem is, I cannot find any information about this, and I checked :

  • here : http://php.net/manual/en/migration70.new-features.php
  • and here : http://php.net/manual/en/migration71.new-features.php
  • and here : http://php.net/manual/en/functions.arguments.php

And same with 7.2, but since the code only requires 7.1, it seems rather normal.

I also googled, and searched here, but either this is not documented or the question marks topic is defeating search engines.

So I feel a little dumb now, and I would really appreciate if someone could enlighten me on the significance of this question mark in method signatures arguments.

Thanks


It's a new feature in php7.1

http://php.net/manual/en/migration71.new-features.php

A question mark means that the type hinted parameter (or return value) is also allowed to be null.

So in your example $arg can be null or any integer.


Just a note to add to the previous answers - it must be either null or have a value in the specified type i.e. - you cannot just omit it - have a look at an example:

class TestClass {

    public function fetch(?array $extensions)
    {
        //...
    }        
}

Now if you call

(new TestClass)->fetch();

this will throw

ArgumentCountError : Too few arguments to function fetch() ...

To make it work without passing array of $extensions you'd have to call it with null as argument

(new TestClass)->fetch(null);

It works best in the situations, where you are passing argument initially set to null to another method for processing i.e.

class TestClass {

    public function fetch(array $extensions = null)
    {
        //...

        $this->filter($extensions);
    }

    private function filter(?array $extensions)
    {
        //...
    }
}

Now you can call the fetch method without the argument

(new TestClass)->fetch();