This is an old revision of the document!
PHP RFC: Declaring Nullable Types
- Version: 0.1
- Date: 2014-04-10
- Author: Levi Morrison levim@php.net
- Status: Draft
- First Published at: https://wiki.php.net/rfc/nullable_typehints
Introduction
This RFC proposes new syntax to allow type declarations to also accept null
without a default value.
Consider the function:
function foo(DateTime $time, $a) {}
In this situation you are not allowed to pass null
for the$time
parameter; this proposal allows you do pass null
without using a default (= null
).
Proposal
This proposal adds a mark ?
to indicate that a type can also be null
. This is allowed for any declared type including array
and callable
.
The ?
marker can be placed on any parameter position, provided it does not violate inheritance rules:
function f(?callable $p, $a) {} // valid
Note that nullable parameters are required; you cannot omit the parameter.
Inheritance in parameters
The ?
marker cannot be removed in a sub-class; it can be added if not present in a super-class. This behavior is consistent with the Liskov substitution principle.
// Valid use: loosening the nullable marker in a parameter: interface Fooable { function foo(Fooable $f); } interface Foo extends Fooable { function foo(?Fooable $f); }
// Invalid use: tightening the nullable marker in a parameter: interface Fooable { function foo(?Fooable $f); } interface Foo extends Fooable { function foo(Fooable $f); }
Return Types
If the RFC for Declaring Return Types passes, then nullable types would be extended to return types as well; this is a major motivator for introducing this new syntax as return types cannot specify a null default to get around the type check.
Here's an example of a binary tree class that uses the ?
marker for both parameter and return types:
// Possible usage of ? modifier for both parameters and return types class BinaryTree { public $value; private $right; private $left; function right(): ?BinaryTree { return $this->right; } function left(): ?BinaryTree { return $this->left; } function setRight(?BinaryTree $t) { $this->right = $t; } function setLeft(?BinaryTree $t) { $this->left = $t; } }
Note that it doesn't really make sense to call $btree->setLeft();
without a parameter; the ?
better reflects the ability to accept BinaryTree
or null
than a default value of null
in this case.
Inheritance in Return Types
In return types the ?
marker would behave differently during inheritance than a parameter type would. In a return type, the null marker can be removed by a subclass, but it cannot be added:
interface Fooable { function foo(): ?Fooable; } interface StrictFooable extends Fooable { function foo(): Fooable; // valid }
interface Fooable { function foo(): Fooable; } interface LooseFooable extends Fooable { function foo(): ?Fooable; // invalid }
Differences from Default Parameters
The null marker does not have a default; it does not default to null
. The following snippet would result in an error:
function f(?callable $p) {} f(); // invalid; function f does not have a default
Proposed PHP Version(s)
This RFC targets 5.7 or 6.0, whichever comes first.
RFC Impact
To Backward Incompatibility
This RFC maintains backwards compatibility. This RFC does not deprecate the default value syntax.
To SAPIs
This RFC has no impact to SAPIs.
To Existing Extensions
TODO
New Constants
This RFC does not propose any new constants or ini defaults.
Open Issues
Make sure there are no open issues when the vote starts!
Unaffected PHP Functionality
This RFC does not deprecate the default value syntax. While there is some overlap of features between it and this RFC, they serve different purposes. As such, the default value syntax will remain.
Future Scope
TODO
Proposed Voting Choices
This RFC modifies the PHP language syntax and therefore requires a two-third majority of votes.
Patches and Tests
There is currently no patch.
Implementation
TODO
After the project is implemented, this section should contain
- the version(s) it was merged to
- a link to the git commit(s)
- a link to the PHP manual entry for the feature
References
TODO