Functional Null Coalesce for PHP

A simple-looking construct is needed for the use of sometimes-declared variables. After considering alternatives, I propose adding a function-like language construct for the purpose of coalescing undeclared variables.

The common challenge: Need to test the value of a variable whose existence is unknown.

Existing solutions:

$input = $_POST['input'] ?? 'none';
if ($input === 'yes') echo 'success';

$_POST['input'] ??= 'none';
if ($_POST['input'] === 'yes') echo 'success';

Needed solution: What we don’t have is a Variable Handling Function that will concisely resolve any uninitialized variable.

// Hypothetical
if (nullc($_POST['input']) === 'yes') echo 'success';

The proposed construct nullc(mixed $var): mixed will return the original value, or null if the variable is not declared.  This is consistent with the construct isset which returns false when a variable is assigned to null.  In this way, the two constructs isset and nullc will complement each other more concisely than something like the construct empty.

The other challenge: Null coalescing operator precedence causes unexpected behavior.

$test = 'off';

if ($test ?? '' === 'on') {
    // The line above is equivalent to if ($test ?? false) and will evaluate as true.
    echo 'yes';
}

if ('on' === $what ?? '') {
    // The line above is equivalent to if (('on' === $what) ?? '') and will throw a warning
}

This requires an extra set of parentheses to be workable.

$test = 'off';

if (($test ?? '') === 'on') {
    // The line above will evaluate as false.
}

These nuances were missed in the former Unary Coalesce RFC. Adding or not adding an operator doesn’t resolve the cumbersome precedence already in place for ?? usage.  I was reminded of the need for a function-style construct while contemplating the differences between PHP’s ?? operator and Microsoft’s function Nz.  What we can do with an expression like nullc($test) === 'on' should be compatible with other existing operators and is more elegant than operators-in-parentheses or any multi-line statements.  This would also resolve the problem of not being able to do the same in a user function.

Leave a Reply

Your email address will not be published. Required fields are marked *