2015-02-06 2 views
-2

У меня есть следующая инструкция switch.Оператор switch с использованием strstr всегда проверяет как true?

URL-адрес содержит идентификатор реферала, например, твиттер, facebook или электронную почту, например [email protected] Это хранится в $ref

У меня есть следующий переключатель заявление:

switch ($ref) { 
    case "twitter": 
     echo "twitter"; 
     break; 
    case "facebook": 
     echo "facbeook"; 
     break; 
    case "blog": 
     echo "blog"; 
     break; 
    case strstr($ref,'@'): 
     echo "email = ".$ref; 
    default: 
     echo "no referral found"; 
     break; 
} 

Однако, если URL передается ни с чем (например просто www.mything.co.uk), то я желаю, чтобы пойти в default случае.

Вместо этого я получаю следующий результат:

email = no referral found 

Почему по умолчанию также включать в себя текст, я поставил для case strstr($ref,'@')?

+0

Не делайте этого: 'случай strstr ($ реф, '@ '): 'Это ужасная практика. –

+0

@BartHaalstra вы можете объяснить, почему это ужасная практика. – Francesca

+0

Это не то, для чего создан переключатель. Коммутатор должен соответствовать переменной статическому значению. Почти все другие языки даже не допускают динамического значения в этом случае. Просто удалите этот случай и выполните оператор if в случае по умолчанию. –

ответ

2

OP вопрос: "Почему по умолчанию также включать в себя текст, я набор для случая strstr ($ ref, '@')? "

Ответ: нет break; после выхода, и, таким образом, проваливается в случае по умолчанию.

UPDATE: Решение проблемы положить заявление в case, я также в том числе легкой работы вокруг:

switch ($ref) { 
    case "twitter": 
     echo "twitter"; 
     break; 
    case "facebook": 
     echo "facbeook"; 
     break; 
    case "blog": 
     echo "blog"; 
     break; 
    default: 
     if (strstr($ref,'@')) { 
      echo "email = ".$ref; 
     } else { 
      echo "no referral found"; 
     } 
     break; 
} 
-1

Это потому, что ваш тест выполняется как if ($ref == strstr($ref, '@')), где strstr возвращает false, который равен пустой строке. Вы действительно не можете использовать динамические сравнения в операциях switch. Используйте if..else, если вам это нужно. Кроме того, злоупотребление switch немного:

switch (true) { 
    case $ref == 'twitter': 
     .. 
    case strstr($ref, '@'): 
     .. 
} 
-1

Это будет работать:

case (strstr($ref, '@') ? true : false): 

Но это не очень хорошо на практике.

+0

1) 'strstr' уже возвращает значение * truey * или' false', то есть явно указывать это на логическое значение не сильно меняется. 2) Это все равно не получится. – deceze

1

Когда $ref пустая строка, то strstr($ref,'@'); возвращает пустую строку тоже именно поэтому case strstr($ref,'@'): соответствует входному выключателю $ref. Проблема заключается в том, вы не можете даже использовать функцию проверки электронной почты, как

filter_var($ref, FILTER_VALIDATE_EMAIL) 

Это будет возвращать false в случае пустого ввода вместо пустой строки, но switch делает свободное сравнение, а это означает, что "" == false вернется true:

http://php.net/manual/en/types.comparisons.php#types.comparisions-loose

Таким образом, единственное решение, которое я вижу, это использовать, если заявление с помощью === оператора:

if($ref == 'twitter') { 
     echo "twitter"; 
} else if($ref == 'facebook') { 
     echo "facbeook"; 
} else if($ref == 'blog') { 
     echo "blog"; 
} else if($ref === filter_var($ref, FILTER_VALIDATE_EMAIL)) { 
     echo "email = ".$ref; 
} else { 
     echo "no referral found"; 
} 
Смежные вопросы