Как назначить первую не ложную переменную из группы из них - PullRequest
6 голосов
/ 02 июля 2011

Я пробовал этот способ без эффекта:

$a = false;
$b = false;
$c = 'sometext';
$result = $a or $b or $c or exit('error: all variables are false');

и $ result должны быть установлены в $ c, но вместо этого это дает значение bool(false).

Ответы [ 4 ]

11 голосов
/ 23 мая 2012

А как же:

$result = $a ?: $b ?: $c ?: exit('doh!');
4 голосов
/ 02 июля 2011
($result = $a) || ($result = $b) || ($result = $c) || exit("no");

или если вы хотите, чтобы 0, пустая строка и т. Д. Не считались ложными:

(($result = $a) !== false) || (($result = $b) !== false) || (($result = $c) !== false) || exit("no");

подумайте, действительно ли это читаемо.Вы также можете использовать старомодный способ:

if ($a !== false)
  $result = $a;
elseif ($b !== false)
  $result = $b;
elseif ($c !== false)
  $result = $c;
else
  exit("no");

Редактировать: на тот случай, если вам когда-нибудь понадобится что-то динамическое; -).

foreach(array('a','b','c') as $key)
  if (($result = $$key) !== false)
    break;
if ($result === false)
  exit("no");
2 голосов
/ 02 июля 2011

Здесь происходит несколько вещей:

Во-первых, в PHP результатом логической операции является логическое значение.

Во-вторых, и более тонко, «английские» логические операторы (or и and) имеют низкий приоритет - ниже, чем оператор присваивания, =.

Поэтому в этом выражении $result всегда получит фактическое значение $ a (независимо от значения $a), поскольку присваивание применяется до логического оператора .

// This has the same effect:
$result = $a or $b or $c;

// As this:
$result = $a;
$a or $b or $c; // this has no effect

Это сбивает с толку, и почти наверняка не то, что вы хотите.

Чтобы получить логический результат того, является ли любой из $a, $b, $c правдивым (то есть true или преобразуемым в true), вы можете использовать скобки для принудительного определения приоритета или использовать операторы в стиле C (|| и &&), которые имеют более высокий приоритет:

// These all have the same effect:

$result = ($a or $b or $c);
$result = $a || $b || $c;

if ($a or $b or $c)
  $result = true;
else
  $result = false;

if ($a || $b || $c)
  $result = true;
else
  $result = false;

Если вы не уверены в приоритетах операторов, лучше использовать круглые скобки - они также, как правило, помогают сделать код более читабельным, поскольку порядок вычисления сделан гораздо более очевидным.

Как правило, лучше не полагаться на неявные преобразования типов (особенно приведение нечисловых строк), поскольку это приводит к нечеткому коду.

редактирование:

Чтобы ответить на реальный вопрос, другой подход (хотя я действительно не рекомендую его в этом случае, так как вы говорите, что вас интересует только первое не ложное значение) должен использовать array_filter без обратного вызова - это вернет массив всех значений во входном массиве, которые являются правдивыми, с сохранением ключей.

например:

$a = false;
$b = false;
$c = 'sometext';
$result = array_filter(array($a, $b, $c));

var_dump($result);

Выходы:

array(1) {
  [2]=>
  string(8) "sometext"
}
2 голосов
/ 02 июля 2011

Результат логического оператора в php логический.

$a = false;
$b = false;
$c = 'sometext';
$result = null;

foreach(array('a', 'b', 'c') as $k)
{
    if($$k !== false)
    {
        $result = $$k;
        break;
    }
}

Также рассмотрите возможность перемещения ваших переменных в массив.

...