С# нулевой коалесцирующий оператор (??) в PHP?
Существует ли в PHP какой-либо тернарный оператор или тому подобное, который действует как ??
для С#?
??
в С# чист и короче, но в PHP вы должны сделать что-то вроде:
// 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';
Ответы
Ответ 1
PHP 7 добавляет оператор null coalesce:
// 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';
Вы также можете посмотреть короткий способ написания php trernary operator ?: (только php >= 5.3)
// Example usage for: Short Ternary Operator
$action = $_POST['action'] ?: 'default';
// The above is identical to
$action = $_POST['action'] ? $_POST['action'] : 'default';
И ваше сравнение с С# не справедливо. "В PHP вы должны сделать что-то вроде:" В С# у вас также будет ошибка времени выполнения, если вы попытаетесь получить доступ к несуществующему элементу массива/словаря.
Ответ 2
Оператор Null Coalesce, (??
) был принят и реализован в PHP 7. Он отличается от короткого тройного оператора (?:
) тем, что ??
будет подавлять E_NOTICE
, который в противном случае возник бы при попытке получить доступ к массиву, где он У меня есть ключ. Первый пример в RFC дает:
$username = $_GET['user'] ?? 'nobody';
// equivalent to: $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
Обратите внимание, что оператор ??
не требует ручного приложения isset
для предотвращения E_NOTICE
.
Ответ 3
Я использую функцию. Очевидно, что это не оператор, но кажется более чистым, чем ваш подход:
function isset_or(&$check, $alternate = NULL)
{
return (isset($check)) ? $check : $alternate;
}
Использование:
isset_or($_REQUEST['test'],'hi');
Ответ 4
До PHP 7 нет. Если вам нужно включить isset
, шаблон для использования - isset($var) ? $var : null
. Нет оператора ?:
, который включает в себя характеристики isset
.
Ответ 5
??
является двоичным в С#, а не тройным. И он не имеет эквивалентности в PHP до PHP 7.
Ответ 6
Аналогичный оператор не существует с PHP 5.6, но вы можете сделать функцию, которая ведет себя аналогично.
/**
* 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 $value must
* not be a valid $key. Otherwise, $value and the immediately following
* $value will be treated as an array-key pair $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;
}
Использование:
$option = first($option_override, $_REQUEST, 'option', $_SESSION, 'option', false);
Это будет проверять каждую переменную, пока не найдет ту, которая удовлетворяет isset()
:
-
$option_override
-
$_REQUEST['option']
-
$_SESSION['option']
-
false
Если бы 4 не было, по умолчанию было бы null
.
Примечание. Там есть более простая реализация, которая использует ссылки, но имеет побочный эффект установки проверяемого элемента в null, если он еще не существует. Это может быть проблематичным, когда имеет значение размер или правдивость массива.