====== PHP RFC: Unary null coalescing operator ======
* Version: 1.0
* Date: 2017-06-21
* Author: Andrea Faulds, ajf@ajf.me
* Status: Declined
* First Published at: http://wiki.php.net/rfc/unary_null_coalescing_operator
===== Introduction =====
[[rfc:isset_ternary|PHP 7.0 introduced the Null Coalescing Operator]] (??), which provides a convenient, more concise alternative to isset() or an explicit NULL check when retrieving the values of variables, properties and object members. Specifically, it provides the short syntax $foo ?? $bar which returns $foo if it exists and is not NULL, or otherwise $bar. This is useful when, for example, retrieving data from query parameters or a configuration file.
One use of the ?? operator is not to retrieve a value per se, but to check its value without worrying about whether it exists, for instance $_GET["action"] ?? NULL === "submit" lets you check if there is a query parameter named ''action'' that is set to ''submit'', which is considerably shorter and less redundant than typing out isset($_GET["action"]) && $_GET["action"] === "submit".
It is this latter use-case that this RFC concerns. While ?? NULL is significantly better than the full expression using isset(), it is still redundant, since we have to provide some arbitrary default value. A shorter alternative would be to use the error-suppression operator (@), but it is slow and considered bad practice.
Thus, this RFC proposes a small tweak to ??.
===== Proposal =====
This RFC proposes a unary version of ??, which would be equivalent to the normal binary version where the second argument is NULL. That is, $foo?? would now be valid, and behave identically to $foo ?? NULL in every respect.
The unary form of ?? would provide a faster, non-proscribed alternative to @ for retrieving possibly-unset variables. It would also provide a concise, non-redundant way to check the value of a possibly-unset variable.
One practical use is optional request parameters:
if ($_POST["action"]?? === "submit") {
// Form submission logic
} else {
// Form display logic
}
Another is optional options in, say, a configuration object, or an “options bag” parameter:
if ($optionsBag->safeMode?? === TRUE) {
// Safe mode
} else {
// Not safe
}
===== Backward Incompatible Changes =====
None.
There is an ambiguity in the case where unary ?? is followed by an operator that can be either unary or binary, i.e. $a?? + $b and $a?? - $b. These continue to be parsed the same ($a ?? (+$b), $a ?? (-$b)), meaning there is no backwards-compatibility break.
===== Proposed PHP Version(s) =====
Next PHP 7.x, which would be PHP 7.2 at the time of writing.
===== RFC Impact =====
==== To SAPIs, Existing Extensions and Opcache ====
There is no effect on any of these, with the exception of extensions inspecting the AST, for which the unary ?? is indistinguishable from ?? NULL.
===== Unaffected PHP Functionality =====
The behaviour of binary ?? is unchanged, as is isset().
===== Future Scope =====
None.
===== Vote =====
This is a simple language change which should only require a 2/3 majority vote on whether or not to approve it.
Voting started 2017-07-11 and ends 2017-07-18 ended 2017-07-18.
* Yes
* No
===== Patches and Tests =====
A php-src patch, including a test, can be found here: https://github.com/php/php-src/pull/2589
A patch for the language specification, including the same test, can be found here: https://github.com/php/php-langspec/pull/197
===== 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
- a link to the language specification section (if any)
===== References =====
* [[rfc:isset_ternary|PHP RFC: Null Coalesce Operator]]