This is an old revision of the document!
PHP RFC: Nullsafe Calls
- Version: 0.1
- Date: 2014-10-22
- Author: Josh Watzman (jwatzman@fb.com), Drew Paroski
- Status: Draft
- First Published at: https://wiki.php.net/rfc/nullsafe_calls
Introduction
This RFC proposes a new operator, the “nullsafe” operator ?->
, which allows safe chaining of method calls. This is useful to easily propagate errors forward to the end of a computation which should fail if any of its sub-computations should fail.
Proposal
A very common pattern is to have some a computation consisting of a series of method calls, any one of which can return null. If any of them do return null, the entire computation should fail. Right now, writing something like this in PHP requires a bunch of boilerplate checks after each call. For example:
function f($o) { $o2 = $o->mayFail1(); if ($o2 === null) { return null; } $o3 = $o2->mayFail2(); if ($o3 === null) { return null; } $o4 = $o3->mayFail3(); if ($o4 === null) { return null; } return $o4->mayFail4(); }
This certainly works, but it's a lot of boilerplate for a fairly common pattern, and it's also a lot of explicit checks that the runtime must do. Instead, a new operator is added to the language: ?->
. Calling $obj?->foo(..)
behaves identically to $obj->foo(..)
if $obj
is not null. If $obj
is null, then it returns null.
This means that calls using this new operator can be chained together. For example, the code above, rewritten with the new operator:
function f($o) { return $o?->mayFail1()?->mayFail2()?->mayFail3()?->mayFail4(); }
Short Circuit
If $obj
is null, when $obj?->foo(..)
executes, the arguments will still be evaluated. In other words, ?->
does not have short circuit semantics when evaluating arguments.
TODO: why?
TODO: this has deep implications for the implementation, we can't avoid actually doing the call
Implications
For the purpose of clarity, some implications of the above definition; all of these stem from consistency between ->
and ?->
, and trying to avoid strange behavioral changes when the left-hand side is or is not null.
- If
$obj
is an object whose class does not define a method “foo”, then$obj?->foo(..)
will still raise a fatal error. - If
$obj
is anything other than null or object, then$obj?->foo(..)
will still raise a fatal error.
Prior Art
- C#, CoffeeScript, and Groovy all have a “safe navigation operator” which was the original inspiration for this feature.
- Hack has already implemented a proposal identical to this one.
Backward Incompatible Changes
What breaks, and what is the justification for it?
Proposed PHP Version(s)
This is proposed for the next major version of PHP, currently PHP 7.
RFC Impact
To Existing Extensions
Will existing extensions be affected?
New Constants
Describe any new constants so they can be accurately and comprehensively explained in the PHP documentation.
Open Issues
Make sure there are no open issues when the vote starts!
Unaffected PHP Functionality
This RFC does not change any existing PHP behavior, including the ->
operator, the ??
operator, or other error suppression mechanisms.
Future Scope
The ?->
operator is not valid to use for a member access, and will generate an E_COMPILE_ERROR
if this is attempted. Defining such functionality is left to a further RFC.
Proposed Voting Choices
This is pretty clearly a core language change and so requires 2/3. The vote will be a straight yes/no vote on accepting the new operator.
Patches and Tests
- php-src: I have a scratch branch at https://github.com/jwatzman/php-src/compare/nullsafe-scratch?expand=1 with a working implementation. As the RFC progresses, I plan to squash that down into a nicer PR for review.
- PHP spec: nothing yet, but this shouldn't take too long.
- PHP docs: import Hack's documentation when they add it: https://github.com/hhvm/hack-hhvm-docs/issues/360 (that task will get completed well before this RFC is voted on, accepted, merged, etc)
Implementation
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
HHVM's implementation for the Hack language is at https://github.com/facebook/hhvm/commit/8fd5a78b02d2d62538e77fcbc927df759c1722f9.
Rejected Features
Keep this updated with features that were discussed on the mail lists.