[PHP-DEV] Coalescing and nullsafe same time

Sorry for raising such an ancient topic.

Аccidentally noticed, that construction like `$arr['undefined']?->foo()->bar` causes error, and not behaves the same, as `($arr['undefined'] ?? null)?->foo()->bar`.

Readed docs, PHP: rfc:nullsafe_operator, asked google and learned, that there were much discussions about such behavior, and it was chosen deliberately. Nevertheless, structures like `(($arr['undefined'] ?? null)?->foo()->bar)` does not looks pretty for me. `$arr['undefined']->foo->bar ?? null` works great, until function calls appears in chain, and `$arr['undefined']->foo()->bar ?? null` breaks. It looks like objects are our favorites for short and safe operations, but arrays are not.

But during development, you can equally easily encounter typed arrays (for example, with a structure described through phpdocs), and working directly with properties, and traditional getters. An structured associative array that has optional fields is also a common pattern. And in large projects these patterns they can be found in almost any combination.

So it looks like the language needs a construct for pretty code in such cases. What do you think it should look like?

* Make nullsafe operator to be coalescing too. Making `$arr['undefined']?->foo()->bar` no to cause error, but return null

* Some new coalescing-nullsafe-operator, `??->`. `$arr['undefined']??->foo()->bar` suppressing all errors to the left same way `??` does.

* Some new nullsafe-array-access operator `$arr?-['key']`. This leads to `$arr?-['key']->foo()->bar` for cases where we are sure that array has key. Supposed short-circuiting working here too.

* Some new coalesce-array-access operators `$arr??-['key']`. Making `$arr??-['key']->foo()->bar` for cases, there we are not sure, that array has key.

* Suppress function call on nulls and undefined errors in `$var->foo()->bar() ?? null`.

Vadim Dvorovenko <vadim.dvorovenko@gmail.com>:

Sorry for raising such an ancient topic.

Аccidentally noticed, that construction like
$arr['undefined']?->foo()->bar causes error, and not behaves the same,
as ($arr['undefined'] ?? null)?->foo()->bar.

Readed docs, https://wiki.php.net/rfc/nullsafe_operator, asked google
and learned, that there were much discussions about such behavior, and
it was chosen deliberately. Nevertheless, structures like
(($arr['undefined'] ?? null)?->foo()->bar) does not looks pretty for
me. $arr['undefined']->foo->bar ?? null works great, until function
calls appears in chain, and $arr['undefined']->foo()->bar ?? null
breaks. It looks like objects are our favorites for short and safe
operations, but arrays are not.

But during development, you can equally easily encounter typed arrays
(for example, with a structure described through phpdocs), and working
directly with properties, and traditional getters. An structured
associative array that has optional fields is also a common pattern. And
in large projects these patterns they can be found in almost any
combination.

So it looks like the language needs a construct for pretty code in such
cases. What do you think it should look like?

  • Make nullsafe operator to be coalescing too. Making
    $arr['undefined']?->foo()->bar no to cause error, but return null

  • Some new coalescing-nullsafe-operator, ??->.
    $arr['undefined']??->foo()->bar suppressing all errors to the left
    same way ?? does.

  • Some new nullsafe-array-access operator $arr?-['key']. This leads to
    $arr?-['key']->foo()->bar for cases where we are sure that array has
    key. Supposed short-circuiting working here too.

  • Some new coalesce-array-access operators $arr??-['key']. Making
    $arr??-['key']->foo()->bar for cases, there we are not sure, that
    array has key.

  • Suppress function call on nulls and undefined errors in
    $var->foo()->bar() ?? null.

Hi, Vadim!

I’ve seen discussions about that and also considered proposing something similar, so thank you for bringing that up!

I see two questions here:

  1. Accessing an array offset on a nullable value ($arrayOrNull[‘offset’])
  2. Treating a non-existent array offset as null ($objects[0]?->prop)

For the first case, the syntax could be symmetric to ?->:

? + → = ?->
? + [$offset] = ?[$offset]

$arrayOrNull?[‘offset’] , equivalent to $arrayOrNull === null ? null : $arrayOrNull[‘offset’]

For the second case:

$objects[?0]?->prop , equivalent to ($objects[0] ?? null)?->prop


Valentin