Лучший способ присвоить переменной значение по умолчанию (имитировать Perl ||, || =)

72

Мне нравится делать такие вещи в Perl: $foo = $bar || $baz назначать $baz на $foo, если $bar пуст или undefined. У вас также есть $foo ||= $bletch, который присваивает $bletch $foo, если $foo не определено или пусто.

Тернарный оператор в этой ситуации утомительный и утомительный. Наверняка существует простой, элегантный метод, доступный в PHP?

Или это единственный ответ на пользовательскую функцию, которая использует isset()?

  • 1
    Связано с проверкой кода : codereview.stackexchange.com/q/12722/31433
  • 1
    Кстати, операторы Perl с желаемой функциональностью - это // и //= и они существуют с Perl v5.10.0. Оригинал || и ||= проверка на логическое значение, а не на определенность.
Показать ещё 5 комментариев
Теги:
operators
default-value

5 ответов

151
Лучший ответ

PHP 5.3 имеет сокращенный оператор ?::

$foo = $bar ?: $baz;

Что назначает $bar, если это не пустое значение (я не знаю, как это было бы иначе в PHP от Perl), в противном случае $baz и такое же, как в Perl и более старых версиях PHP:

$foo = $bar ? $bar : $baz;

Но PHP не имеет для этого сложного оператора присваивания (т.е. никакого эквивалента Perl ||=).

Кроме того, PHP будет создавать шум, если $bar не установлен, если вы не отключите уведомления. Существует также семантическая разница между isset() и empty(). Первая возвращает false, если переменная не существует или установлена ​​на NULL. Последний возвращает true, если он не существует, или установлен в 0, '', false или NULL.

  • 2
    +1 За то, что познакомил меня с еще одной замечательной функцией 5.3, которую я пропускаю на своих серверах RHEL5 / PHP5.1.2.
  • 0
    Я предполагаю, что вы имеете в виду The first returns вместо The second в вашем предпоследнем предложении.
Показать ещё 2 комментария
39

В PHP 7 у нас наконец есть способ сделать это элегантно. Он называется оператором Null coalescing. Вы можете использовать его следующим образом:

$name = $_GET['name'] ?? 'john doe';

Это эквивалентно

$name = isset($_GET['name']) ? $_GET['name']:'john doe';
  • 11
    Для того, чтобы использовать самое вызывающее, круто звучащее имя для оператора, когда-либо.
  • 12
    Я бы сказал, что у оператора космического корабля тоже есть свои плюсы.
Показать ещё 1 комментарий
7

Спасибо за отличные ответы!

Для всех, кто придет сюда для возможной альтернативы, вот некоторые функции, которые помогают вывести скуку из такого рода вещей.

function set_if_defined(&$var, $test){
    if (isset($test)){
        $var = $test;
        return true;
    } else {
        return false;
    }
}

function set_unless_defined(&$var, $default_var){
    if (! isset($var)){
        $var = $default_var;
        return true;
    } else {
        return false;
    }
}

function select_defined(){
    $l = func_num_args();
    $a = func_get_args();
    for ($i=0; $i<$l; $i++){
        if ($a[$i]) return $a[$i];
    }
}

Примеры:

// $foo ||= $bar;
set_unless_defined($foo, $bar);

//$foo = $baz || $bletch
$foo = select_defined($baz, $bletch);

Я уверен, что их можно улучшить.

7

Общая идиома для совместимости со старыми версиями PHP:

 $var = $bool   or   $var = "default";
 // If I use it, then only with excessive spaces for clarity.

Это работает для значений, которые могут быть оценены в булевом контексте. Преимущество здесь в том, что он также дает вам указанную отладку e_notice, если переменная be undefined.

  • 0
    Разве уведомление не отправляется с $bool ? $bool : "default" если $bool не определен?
  • 0
    Конечно, это то же самое. Я предположил, что OP относится к isset($var) ? $var : DEFAULT . Но звучит так, будто он все равно хочет их избегать.
1

В PHP раньше, чем 7. *, можно использовать?: для переменной undefined с ошибками, локально подавленными с помощью @:

$foo = @$bar ?: $baz;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню