C#'s null coalescing operator (??) in PHP

PhpTernary OperatorNull Coalescing-OperatorPhp 7

Php Problem Overview


Is there a ternary operator or the like in PHP that acts like ?? of C#?

?? in C# is clean and shorter, but in PHP you have to do something like:

// This is absolutely okay except that $_REQUEST['test'] is kind of redundant.
echo isset($_REQUEST['test'])? $_REQUEST['test'] : 'hi';

// This is perfect! Shorter and cleaner, but only in this situation.
echo null? : 'replacement if empty';

// This line gives error when $_REQUEST['test'] is NOT set.
echo $_REQUEST['test']?: 'hi';

Php Solutions


Solution 1 - Php

PHP 7 adds the null coalescing operator:

// Fetches the value of $_GET['user'] and returns 'nobody'
// if it does not exist.
$username = $_GET['user'] ?? 'nobody';
// This is equivalent to:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

You could also look at short way of writing PHP's ternary operator ?: (PHP >=5.3 only)

// Example usage for: Short Ternary Operator
$action = $_POST['action'] ?: 'default';

// The above is identical to
$action = $_POST['action'] ? $_POST['action'] : 'default';

And your comparison to C# is not fair. "in PHP you have to do something like" - In C# you will also have a runtime error if you try to access a non-existent array/dictionary item.

Solution 2 - Php

The Null Coalesce Operator, (??) has been accepted and implemented in PHP 7. It differs from the short ternary operator (?:) in that ?? will suppress the E_NOTICE that would otherwise occur when attempting to access an array where it doesn't have a key. The first example in the RFC gives:

$username = $_GET['user'] ?? 'nobody';
// equivalent to: $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

Notice that the ?? operator does not require the manual application of isset to prevent the E_NOTICE.

Solution 3 - Php

I use function. Obviously it is not operator, but seems cleaner than your approach:

function isset_or(&$check, $alternate = NULL)
{
    return (isset($check)) ? $check : $alternate;
}

Usage:

isset_or($_REQUEST['test'],'hi');

Solution 4 - Php

Prior to PHP 7, there isn't. If you need to involve isset, the pattern to use is isset($var) ? $var : null. There's no ?: operator that includes the characteristics of isset.

Solution 5 - Php

?? is binary in C#, not ternary. And it has no equivalence in PHP prior to PHP 7.

Solution 6 - Php

An identical operator doesn't exist as of PHP 5.6, but you can make a function that behaves similarly.

/**
 * Returns the first entry that passes an isset() test.
 *
 * Each entry can either be a single value: $value, or an array-key pair:
 * $array, $key.  If all entries fail isset(), or no entries are passed,
 * then first() will return null.
 *
 * $array must be an array that passes isset() on its own, or it will be
 * treated as a standalone $value.  $key must be a valid array key, or
 * both $array and $key will be treated as standalone $value entries. To
 * be considered a valid key, $key must pass:
 *
 *     is_null($key) || is_string($key) || is_int($key) || is_float($key)
 *         || is_bool($key)
 *
 * If $value is an array, it must be the last entry, the following entry
 * must be a valid array-key pair, or the following entry's $value must
 * not be a valid $key.  Otherwise, $value and the immediately following
 * $value will be treated as an array-key pair's $array and $key,
 * respectfully.  See above for $key validity tests.
 */
function first(/* [(array $array, $key) | $value]... */)
{
	$count = func_num_args();
	
	for ($i = 0; $i < $count - 1; $i++)
	{
		$arg = func_get_arg($i);
		
		if (!isset($arg))
		{
			continue;
		}
		
		if (is_array($arg))
		{
			$key = func_get_arg($i + 1);
			
			if (is_null($key) || is_string($key) || is_int($key) || is_float($key) || is_bool($key))
			{
				if (isset($arg[$key]))
				{
					return $arg[$key];
				}
				
				$i++;
				continue;
			}
		}
		
		return $arg;
	}
	
	if ($i < $count)
	{
		return func_get_arg($i);
	}
	
	return null;
}

Usage:

$option = first($option_override, $_REQUEST, 'option', $_SESSION, 'option', false);

This would try each variable until it finds one that satisfies isset():

  1. $option_override
  2. $_REQUEST['option']
  3. $_SESSION['option']
  4. false

If 4 weren't there, it would default to null.

Note: There's a simpler implementation that uses references, but it has the side effect of setting the tested item to null if it doesn't already exist. This can be problematic when the size or truthiness of an array matters.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondppView Question on Stackoverflow
Solution 1 - PhpzerkmsView Answer on Stackoverflow
Solution 2 - PhpkojiroView Answer on Stackoverflow
Solution 3 - PhpLukLedView Answer on Stackoverflow
Solution 4 - PhpdecezeView Answer on Stackoverflow
Solution 5 - PhpDaniView Answer on Stackoverflow
Solution 6 - PhpZenexerView Answer on Stackoverflow