# [RFC] [DISCUSSION] Improve null-coalescing operator (??) adding empty check (??:)

- Thread: https://externals.io/message/101606
- Original archive: https://news-web.php.net/php.internals/101606
- Started by Lito on 2018-01-17T17:47:49+00:00
- Messages: 7
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #101606 — Lito — 2018-01-17T17:47:49+00:00

URL: https://externals.io/message/101606#101606

Related with Request #75833 https://bugs.php.net/bug.php?id=75833

 From PHP 7 null-coalescing operator is a great option to avoid a 
previous exists check with isset.

But I think that this comaparison can be improved adding a ternary 
operator like ??: and check also empty values.

Example:

--------------------------------------

<?php

$foo = '';

// Current response with ternary operator

echo $foo ?: 'default'; // 'defaut'

// Current response with null-coalescing operator

echo $foo ?? 'default'; // ''

// Possible response with ternary null-coalescing operator

echo $foo ??: 'default'; // 'defaut'

// Same response with current PHP available code

echo (isset($foo) && $foo) ? $foo : 'default'; // 'default'

/** ------------------------------- **/

$foo = false;

// Current response with ternary operator

echo $foo ?: 'default'; // 'defaut'

// Current response with null-coalescing operator

echo $foo ?? 'default'; // false

// Possible response with ternary null-coalescing operator

echo $foo ??: 'default'; // 'defaut'

// Same response with current PHP available code

echo (isset($foo) && $foo) ? $foo : 'default'; // 'default'

/** ------------------------------- **/

$foo = null;

// Current response with ternary operator

echo $foo ?: 'default'; // 'defaut'

// Current response with null-coalescing operator

echo $foo ?? 'default'; // 'defaut'

// Possible response with ternary null-coalescing operator

echo $foo ??: 'default'; // 'defaut'

// Same response with current PHP available code

echo (isset($foo) && $foo) ? $foo : 'default'; // 'default'

/** ------------------------------- **/

unset($foo);

// Current response with ternary operator

echo $foo ?: 'default'; // PHP Notice:  Undefined variable: foo

// Current response with null-coalescing operator

echo $foo ?? 'default'; // 'defaut'

// Possible response with ternary null-coalescing operator

echo $foo ??: 'default'; // 'defaut'

// Same response with current PHP available code

echo (isset($foo) && $foo) ? $foo : 'default'; // 'default'

--------------------------------------

What about?

Thanks!
Lito.

---

## #101608 — Marco Pivetta — 2018-01-17T18:17:54+00:00

URL: https://externals.io/message/101606#101608 · In reply to: #101606

This:

echo (isset($foo) && $foo) ? $foo : 'default';

Is equivalent to:

echo $foo ?: 'default';

Please don't endorse usage of undefined variables.



> Related with Request #75833 https://bugs.php.net/bug.php?id=75833
>
> From PHP 7 null-coalescing operator is a great option to avoid a previous
> exists check with isset.
>
> But I think that this comaparison can be improved adding a ternary
> operator like ??: and check also empty values.
>
> Example:
>
> --------------------------------------
>
> <?php
>
> $foo = '';
>
> // Current response with ternary operator
>
> echo $foo ?: 'default'; // 'defaut'
>
> // Current response with null-coalescing operator
>
> echo $foo ?? 'default'; // ''
>
> // Possible response with ternary null-coalescing operator
>
> echo $foo ??: 'default'; // 'defaut'
>
> // Same response with current PHP available code
>
> echo (isset($foo) && $foo) ? $foo : 'default'; // 'default'
>
> /** ------------------------------- **/
>
> $foo = false;
>
> // Current response with ternary operator
>
> echo $foo ?: 'default'; // 'defaut'
>
> // Current response with null-coalescing operator
>
> echo $foo ?? 'default'; // false
>
> // Possible response with ternary null-coalescing operator
>
> echo $foo ??: 'default'; // 'defaut'
>
> // Same response with current PHP available code
>
> echo (isset($foo) && $foo) ? $foo : 'default'; // 'default'
>
> /** ------------------------------- **/
>
> $foo = null;
>
> // Current response with ternary operator
>
> echo $foo ?: 'default'; // 'defaut'
>
> // Current response with null-coalescing operator
>
> echo $foo ?? 'default'; // 'defaut'
>
> // Possible response with ternary null-coalescing operator
>
> echo $foo ??: 'default'; // 'defaut'
>
> // Same response with current PHP available code
>
> echo (isset($foo) && $foo) ? $foo : 'default'; // 'default'
>
> /** ------------------------------- **/
>
> unset($foo);
>
> // Current response with ternary operator
>
> echo $foo ?: 'default'; // PHP Notice:  Undefined variable: foo
>
> // Current response with null-coalescing operator
>
> echo $foo ?? 'default'; // 'defaut'
>
> // Possible response with ternary null-coalescing operator
>
> echo $foo ??: 'default'; // 'defaut'
>
> // Same response with current PHP available code
>
> echo (isset($foo) && $foo) ? $foo : 'default'; // 'default'
>
> --------------------------------------
>
> What about?
>
> Thanks!
> Lito.

---

## #101609 — Lito — 2018-01-17T18:28:14+00:00

URL: https://externals.io/message/101606#101609 · In reply to: #101608

No $foo ?: 'default' , it's only equivalent to (isset($foo) && $foo) ? 
$foo : 'default' if $foo exists.

Also PHP has added ?? as null-coalescing operator that works with 
undefined variables/attributes/keys, my proposal is an improvement over 
this one.

I don't want to endorse usage of undefined variables, can be used in a 
large set of situations, like object attributes, array keys, etc...

Anyway thanks for your feedback.
Lito.


> This:
>
> echo (isset($foo) && $foo) ? $foo : 'default';
>
> Is equivalent to:
>
> echo $foo ?: 'default';
>
> Please don't endorse usage of undefined variables.
>
> On 17 Jan 2018 19:00, "Lito" <info@eordes.com 
> <mailto:info@eordes.com>> wrote:
>
>     Related with Request #75833 https://bugs.php.net/bug.php?id=75833
>     <https://bugs.php.net/bug.php?id=75833>
>
> > […]
>     previous exists check with isset.
>
>     But I think that this comaparison can be improved adding a ternary
>     operator like ??: and check also empty values.
>
>     Example:
>
>     --------------------------------------
>
>     <?php
>
>     $foo = '';
>
>     // Current response with ternary operator
>
>     echo $foo ?: 'default'; // 'defaut'
>
>     // Current response with null-coalescing operator
>
>     echo $foo ?? 'default'; // ''
>
>     // Possible response with ternary null-coalescing operator
>
>     echo $foo ??: 'default'; // 'defaut'
>
>     // Same response with current PHP available code
>
>     echo (isset($foo) && $foo) ? $foo : 'default'; // 'default'
>
>     /** ------------------------------- **/
>
>     $foo = false;
>
>     // Current response with ternary operator
>
>     echo $foo ?: 'default'; // 'defaut'
>
>     // Current response with null-coalescing operator
>
>     echo $foo ?? 'default'; // false
>
>     // Possible response with ternary null-coalescing operator
>
>     echo $foo ??: 'default'; // 'defaut'
>
>     // Same response with current PHP available code
>
>     echo (isset($foo) && $foo) ? $foo : 'default'; // 'default'
>
>     /** ------------------------------- **/
>
>     $foo = null;
>
>     // Current response with ternary operator
>
>     echo $foo ?: 'default'; // 'defaut'
>
>     // Current response with null-coalescing operator
>
>     echo $foo ?? 'default'; // 'defaut'
>
>     // Possible response with ternary null-coalescing operator
>
>     echo $foo ??: 'default'; // 'defaut'
>
>     // Same response with current PHP available code
>
>     echo (isset($foo) && $foo) ? $foo : 'default'; // 'default'
>
>     /** ------------------------------- **/
>
>     unset($foo);
>
>     // Current response with ternary operator
>
>     echo $foo ?: 'default'; // PHP Notice:  Undefined variable: foo
>
>     // Current response with null-coalescing operator
>
>     echo $foo ?? 'default'; // 'defaut'
>
>     // Possible response with ternary null-coalescing operator
>
>     echo $foo ??: 'default'; // 'defaut'
>
>     // Same response with current PHP available code
>
>     echo (isset($foo) && $foo) ? $foo : 'default'; // 'default'
>
>     --------------------------------------
>
>     What about?
>
>     Thanks!
>     Lito.

---

## #101610 — Nikita Popov — 2018-01-17T18:36:01+00:00

URL: https://externals.io/message/101606#101610 · In reply to: #101609

> No $foo ?: 'default' , it's only equivalent to (isset($foo) && $foo) ?
> $foo : 'default' if $foo exists.
>
> Also PHP has added ?? as null-coalescing operator that works with
> undefined variables/attributes/keys, my proposal is an improvement over
> this one.
>
> I don't want to endorse usage of undefined variables, can be used in a
> large set of situations, like object attributes, array keys, etc...
>

What is the use case for the ??: operator?

Null-coalesce is very common, because undefined/null are typically used to
signal default values. Using *any* falsy value to indicate a default value
seems a lot more unusual and precarious to me, especially if you consider
PHP's specific semantics around falsiness (with the string "0" being falsy).

Nikita


> 
>
> > […]

---

## #101611 — Andrey Andreev — 2018-01-17T18:43:04+00:00

URL: https://externals.io/message/101606#101611 · In reply to: #101609

Hi,



> No $foo ?: 'default' , it's only equivalent to (isset($foo) && $foo) ? $foo
> : 'default' if $foo exists.
>
> Also PHP has added ?? as null-coalescing operator that works with undefined
> variables/attributes/keys, my proposal is an improvement over this one.
>
> I don't want to endorse usage of undefined variables, can be used in a large
> set of situations, like object attributes, array keys, etc...
>
> Anyway thanks for your feedback.
> Lito.
>

There is a shorter version:

    empty($foo) ? 'default' : $foo;

And I think that's quite convenient for the few use cases it has
(refer to Nikita's reply).

Cheers,
Andrey.

---

## #101612 — Lito — 2018-01-17T18:47:41+00:00

URL: https://externals.io/message/101606#101612 · In reply to: #101611

> Hi,
>
>
> 
> > […]
> There is a shorter version:
>
>      empty($foo) ? 'default' : $foo;
>
> And I think that's quite convenient for the few use cases it has
> (refer to Nikita's reply).
>
> Cheers,
> Andrey.
>
Yes, I think that:

$foo = $foo ??: 'default';

Is more clear and with less code than:

$foo = empty($foo) ? 'default' : $foo;

As ?? does.

Regards,
Lito.

---

## #101997 — Lito — 2018-03-22T13:45:31+00:00

URL: https://externals.io/message/101606#101997 · In reply to: #101612

This is a RFC karma request for my wiki account.

I want to create a RFC with my proposal: Improve null-coalescing 
operator (??) adding empty check (??:)

First list message is: http://news.php.net/php.internals/101606

The main idea is simplify "empty" check on non existing keys or object 
attributes. Same as "?:" but also checking undefined.

Current check:

$value = empty($user->thisOptionalAttributeCanBeEmptyOrNotExists) ? 
'without value' : $user->thisOptionalAttributeCanBeEmptyOrNotExists;

New feature:

$value = $user->thisOptionalAttributeCanBeEmptyOrNotExists ??: 'without 
value';

I think that could be very usefull on inline "exists" + "not empty" 
checks with a more clear code.

It's possible?

Thanks,
Lito.


> 
> > […]
> Yes, I think that:
>
> $foo = $foo ??: 'default';
>
> Is more clear and with less code than:
>
> $foo = empty($foo) ? 'default' : $foo;
>
> As ?? does.
>
> Regards,
> Lito.
