PHP и ?? оператор - PullRequest
       58

PHP и ?? оператор

5 голосов
/ 11 марта 2009

Как некоторые люди знают, в C # есть очень полезный оператор ??, который вычисляет и возвращает выражение справа, если выражение слева равно нулю. Это очень полезно для предоставления значений по умолчанию, например:

int spaces = readSetting("spaces") ?? 5;

Если readSetting не может найти "spaces" и возвращает ноль, переменная spaces будет содержать значение по умолчанию 5.

Вы можете сделать почти то же самое в JavaScript и Ruby с оператором ||, как в

var spaces = readSetting("spaces") || 5;

хотя в этом случае значение spaces в JavaScript не может быть 0, а в Ruby и JavaScript - false.

PHP имеет оператор or и хотя он не работает как || в том смысле, что он не возвращает выражение справа, он все равно может быть полезен здесь:

$spaces = readSetting('spaces') or $spaces = 5;

с примечанием, что "" и "0" также обрабатываются как false в PHP в дополнение к false, 0 и null в большинстве языков.

Вопрос в том, использовать ли конструкцию сверху? Есть ли у него побочные эффекты помимо обработки большого класса символов как ложных? И есть ли лучшая конструкция, которая обычно используется и рекомендуется сообществом PHP для этой задачи?

Ответы [ 5 ]

6 голосов
/ 11 марта 2009

PHP 5.3.0 дает более короткую версию условия троичного оператора? True: false, которая выглядит следующим образом:

$spaces = readSettings('spaces') ?: 5;

Пожалуйста, обратите внимание, что PHP 5.3.0 все еще находится в бета-версии и еще не готов к работе (хотя он уже готов к выпуску), но он предоставляет много новых интересных вещей, таких как лямбда-функции и пространства имен, так что определенно стоит проверить Особенности вне!

Вот статья, которая довольно хорошо описывает новые функции:

http://www.sitepoint.com/article/whats-new-php-5-3/

6 голосов
/ 11 марта 2009

Это хорошая идея, чтобы быть более явным в подобных случаях, особенно в PHP, поскольку он имеет несколько запутанные правила преобразования типов (например, "0" является ложным, как вы указали).

Если вы хотите быть строгим, позвольте вашей функции readSettings вернуть правильную настройку или четко определенное значение, если настройки не найдены, например, null. Тогда вы должны использовать его как:

$spaces = readSettings('spaces');
if (null === $spaces) {
    $spaces = 5;
}

Если вы хотите быть более щедрым и хотите, чтобы $ пробелы были не пустыми, используйте:

$spaces = readSettings('spaces');
if (empty($spaces)) {    // or:  if (!$spaces) {
    $spaces = 5;
}

Вы можете сократить его на стоимость второго вызова функции или некрасивых конструкций (не рекомендуется):

$spaces = readSettings('space') ? readSettings('space') : 5;
$spaces = ($x = readSettings('space')) ? $x : 5;  // UGLY!

Но будьте внимательны, если вы хотите, чтобы 0 было допустимым значением для $spaces!

Из Дзэн Питона :

Явное лучше, чем неявное.

В вашем случае я бы рекомендовал просто добавить второй параметр $default в readSettings():

function readSettings($key, $default=null) {
    return isset($settings[$key]) ? $settings[$key] : $default;
}

$spaces = readSettings('spaces', 5); 
4 голосов
/ 11 марта 2009

Как насчет этого?

$spaces = ($tmp=readSettings('space')) ? $tmp : 5;

Или, более запутанно, но используя только одну переменную:

$spaces = ($spaces=readSettings('space')) ? $spaces : 5;
1 голос
/ 02 октября 2017

PHP 7 теперь поддерживает ?? как Нулевой оператор объединения

Нулевой оператор объединения (??) был добавлен как синтаксический сахар для общего случая необходимости использовать троичный в сочетании с Исеть (). Возвращает свой первый операнд, если он существует и не равен NULL; в противном случае возвращается второй операнд.

<?php 
// 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';

// Coalescing can be chained: this will return the first 
// defined value out of $_GET['user'], $_POST['user'], and 
// 'nobody'. 
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody'; 
?>

http://php.net/manual/en/migration70.new-features.php

1 голос
/ 11 марта 2009

Если вы хотите гарантировать, что вы получите false или null, а не считать такие вещи, как «0», как «false», вы можете сделать следующее:

$spaces = readSetting('spaces');
if($spaces == null || $spaces === false) $spaces = 5;

Оператор === в PHP ищет идентичное совпадение, поэтому "0", "" не будут равны false. Очевидно, что вы можете изменить стиль кода по своему вкусу, но вы поняли идею.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...