Подтвердить что ты не робот

Как проверить, не пусто ли только одна из трех переменных?

У меня есть три переменные:

$var1
$var2
$var3

Я действительно ищу лучший способ проверить, нет ли только одна этих трех переменных, а две другие пусты.

Возможно ли это сделать только с одним if? Если нет, то какой лучший способ?

Все переменные содержат текст.

4b9b3361

Ответ 1

Вы можете преобразовать переменную в массив и исключить пустые переменные, используя array_filter(). Затем используйте count() после фильтра.

if(count(array_filter(array($var1,$var2,$var3)))==1){
  //only 1 variable is not empty
}

Отметьте ссылка Fiddle

Ответ 2

Булевы возвращают 0 и 1 с помощью array_sum()

if (array_sum(array(empty($var1), empty($var2), empty($var3))) == 1)
{
    echo "one is empty" ;
}

ETA: Это более простой способ:

if (!empty($var1) + !empty($var2) + !empty($var3) == 1) {
    echo "1 is not empty" ;
}

ETA 2: нам не нужны отрицательные знаки

if (empty($var1) + empty($var2) + empty($var3) == 2) {
    echo "1 is not empty" ;
}

Ответ 3

$counter=0;
$counter+= empty($var1) ? 0:1;
$counter+= empty($var2) ? 0:1;
$counter+= empty($var3) ? 0:1;

if($counter==1)
   echo "Exactly 2 are empty";

Fiddle

Или вы просто можете сделать

var_dump(count(array_filter(array($var1,$var2,$var3)))==1);

Fiddle

Ответ 4

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

if (!(!empty($var1) && !empty($var2) && !empty($var3)) && (!empty($var1) ^ !empty($var2) ^ !empty($var3))) {
    echo "Only one string is not empty\n";
}

И это примерно на 25% быстрее, чем принятый ответ.

$before = microtime(true);
for ($i = 0; $i < 100000; ++$i) {
    $var1 = 'Hello';
    $var2 = '';
    $var3 = '';

    if (!(!empty($var1) && !empty($var2) && !empty($var3)) && (!empty($var1) ^ !empty($var2) ^ !empty($var3))) {
        echo "Only one string is not empty\n";
    }

    $var4 = '';
    $var5 = '';
    $var6 = '';

    if (!(!empty($var4) && !empty($var5) && !empty($var6)) && (!empty($var4) ^ !empty($var5) ^ !empty($var6))) {
        echo "Only one string is not empty\n";
    }

    $var7 = 'Hello';
    $var8 = 'World';
    $var9 = '!';

    if (!(!empty($var7) && !empty($var8) && !empty($var9)) && (!empty($var7) ^ !empty($var8) ^ !empty($var9))) {
        echo "Only one string is not empty\n";
    }
}

$after = microtime(true);
echo ($after-$before)/$i . " sec for XOR\n";

// 3.2943892478943E-6 sec for XOR

$before = microtime(true);
for ($i = 0; $i < 100000; ++$i) {
    $var1 = 'Hello';
    $var2 = '';
    $var3 = '';

    if (count(array_filter(array($var1, $var2, $var3))) == 1) {
        echo "Only one string is not empty\n";
    }

    $var4 = '';
    $var5 = '';
    $var6 = '';

    if (count(array_filter(array($var4, $var5, $var6))) == 1) {
        echo "Only one string is not empty\n";
    }

    $var7 = 'Hello';
    $var8 = 'World';
    $var9 = '';

    if (count(array_filter(array($var7, $var8, $var9))) == 1) {
        echo "Only one string is not empty\n";
    }
}
$after = microtime(true);
echo ($after-$before)/$i . " sec for Arrays\n";

// 4.3078589439392E-6 sec for Arrays

* Мне пришлось обновить ответ, потому что имя "эксклюзивное" или "несколько вводит в заблуждение в контексте более двух выражений". Конечно, все комментаторы правы, и эксклюзивные, или это двоичная операция, поэтому разрешая слева направо. 1 ^ 1 ^ 1 == 1 разрешается 0 ^ 1 == 1 и поэтому true. Эксклюзив или действительно ищет нечетное число истин.

Я обновил свой ответ с помощью легко читаемого обходного пути, но это определенно не удовлетворяет меня, и я должен администратор, что я решил огромное заблуждение булевых операторов в моем сознании. В прошлый раз было ошибочное предположение о том, что AND и OR были разрешены слева направо, а не сначала AND, а затем OR. *

Ответ 5

Попробуйте следующее:

if (($var1 !== '' && $var2 == '' && $var3 == '') ||
    ($var2 !== '' && $var1 == '' && $var3 == '')  ||
    ($var3 !== '' && $var1 == '' && $var2 == '')) {
    echo 'variable is empty';
}

Ответ 6

Побитовое XOR отлично подходит для этого:

$var1 ^ $var2 ^ $var3

У вас могут возникнуть проблемы, если переменные не будут сбрасываться в boolean легко, и в этом случае вам нужно сделать empty($var) для каждого из них.

Boom. Нуль if s.

Обновление

Ой, если все они не пусты, true ^ true ^ true == true

Вам нужно проверить, что все они являются истинными:

($var1 ^ $var2 ^ $var3) && !($var1 && $var2 && $var3)

Ответ 7

Это ситуация, когда вы должны использовать массивы. Теперь у вас есть только 3 значения, но что, если вам нужно 4? Вам нужно будет изменить весь ваш код!

$var = array();
$var[] = 'abc';
$var[] = '';
$var[] = 0;

// will return 1, empty values, false or 0 (falsy values) will not get counted:
echo count(array_filter($var)).' values found';
if( count(array_filter($var))==1 ){ echo 'exactly one value set'; }

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

Ответ 8

Попробуйте следующее:

$temp_array = array($var1,$var2,$var3);
$temp_count = count(array_filter($temp_array, 'strlen'));
if($temp_count ==1){
    echo "1 variable is not empty";
}
else
{
    echo "total empty variable  is = ".$temp_count;
}

DEMO