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?


It's called a Nullable type, introduced in PHP 7.1.

You could pass a NULL value if there is a Nullable type (with ?) parameter, or a value of the same type.

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 test(?string ...$parameters) {
}

# Usage
test('foo', 'bar', null, 'baz');

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 :

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.

As of PHP 7.4 : Class properties type declarations.

As of PHP 8.0 : Nullable Union Type


The question mark before the string in your function parameter denotes a nullable type. In your above example, $parameter1 must is allowed to have a NULL value, whereas $parameter2 is not; it must contain a valid string.

Parameters with a nullable type do not have a default value. If omitted the value does not default to null and will result in an error:

function f(?callable $p) { }
f(); // invalid; function f does not have a default


That means that the argument is allowed to be passed as the specified type or NULL:

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


This is roughly equivalent to

 public function (string $parameter1 = null, string $parameter2) {}

Except that the argument is still required, and an error will be issued if the argument is omitted.

Specifically in this context, the second argument is required and using =null would make the first optional, which doesn't really work. Sure it works but what I mean that it does not actually make it optional, which is the main purpose of default values.

So using

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

Syntactically makes a bit more sense in this instance.