Search code examples
phpnull-coalescing-operator

Using php null safe and null coalescing operators with an array containing anonymous functions


The following code works as expected:

$array = [];

// null
var_dump($array['foo']->bar ?? null);


// this throws a warning
var_dump($array['foo']?->bar);

The null-coalescing operator supports array while the null-safe operator doesn't.

--

Lets take the following code:

function calculate($num1, $num2, $action)
{
    $actions = [
        "add" => function ($a, $b) {
            return $a + $b;
        },
        "substract" => function ($a, $b) {
            return $a - $b;
        },
        "multiply" => function ($a, $b) {
            return $a * $b;
        },
        "divide" => function ($a, $b) {
            return $a / $b;
        }
    ];

    return $actions[$action]($num1, $num2) ?? "Action forbidden";
}

// 1) int(3)
var_dump(calculate(1, 2, 'add'));

// 2) Warning: Undefined array key "addd"...
var_dump(calculate(1, 2, 'addd'));

If I update the code with:

return $actions[$action] ?? "Action forbidden";

Then it works as expected:

// 3) string(16) "Action forbidden"
var_dump(calculate(1, 2, 'addd'));

Of course, if I update the code this way:

return array_key_exists($action, $actions) ? $actions[$action]($num1, $num2) : "Action forbidden";

// 4) string(16) "Action forbidden"
var_dump(calculate(1, 2, 'addd'));

But it loses all the benefits of null-coalescing...

Question

Why I cannot use null-coalescing with the following format (or what am I missing?):

return $actions[$action]($num1, $num2) ?? "Action forbidden";

Solution

  • Your attempt is using the null-coalescing operator on the result of calling the function. So it won't prevent the undefined array index or calling the null function that results.

    From the Nullsafe Operator RFC

    Future Scope
    ...
    A nullsafe function call syntax ($callableOrNull?()) is also outside of scope for this RFC.

    So this is something that may be addressed in the future, but it's not in the existing design.