divHelper11
divHelper11

Reputation: 2208

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?

Upvotes: 44

Views: 9861

Answers (4)

Syscall
Syscall

Reputation: 19780

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

Upvotes: 48

ArtisticPhoenix
ArtisticPhoenix

Reputation: 21661

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.

Upvotes: 1

sorak
sorak

Reputation: 2633

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

Upvotes: 1

Obsidian Age
Obsidian Age

Reputation: 42304

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

Upvotes: 4

Related Questions