使用 strstr 的 Switch 语句总是验证为真?
Switch statement using strstr always validates as true?
我有以下 switch 语句。
URL 包含推介 ID,例如 twitter、facebook 或电子邮件,例如 mail@mail.com。这存储为 $ref
我有以下 switch 语句:
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,'@')
设置的文本?
那是因为您的测试执行方式类似于 if ($ref == strstr($ref, '@'))
,其中 strstr
returns false
等于空字符串。您不能真正在 switch
语句中使用动态比较。如果需要,请使用 if..else
。或者,滥用 switch
一点:
switch (true) {
case $ref == 'twitter':
..
case strstr($ref, '@'):
..
}
这会起作用:
case (strstr($ref, '@') ? true : false):
但这并不是很好的练习。
当$ref
为空字符串时,strstr($ref,'@');
return也是空字符串,这就是为什么case strstr($ref,'@'):
匹配开关输入$ref.
问题是,您甚至不能使用
这样的电子邮件验证功能
filter_var($ref, FILTER_VALIDATE_EMAIL)
在空输入而不是空字符串的情况下 return false
,但是 switch
进行松散比较,这意味着 "" == false
会 return true
:
http://php.net/manual/en/types.comparisons.php#types.comparisions-loose
因此,我看到的唯一解决方案是使用 ===
运算符的 if 语句:
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";
}
OP 问题:“为什么默认值还包括我为 case strstr($ref,'@') 设置的文本?”
答案:输出后没有break;
,因此通过进入默认情况。
更新: 解决在 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;
}
我有以下 switch 语句。
URL 包含推介 ID,例如 twitter、facebook 或电子邮件,例如 mail@mail.com。这存储为 $ref
我有以下 switch 语句:
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,'@')
设置的文本?
那是因为您的测试执行方式类似于 if ($ref == strstr($ref, '@'))
,其中 strstr
returns false
等于空字符串。您不能真正在 switch
语句中使用动态比较。如果需要,请使用 if..else
。或者,滥用 switch
一点:
switch (true) {
case $ref == 'twitter':
..
case strstr($ref, '@'):
..
}
这会起作用:
case (strstr($ref, '@') ? true : false):
但这并不是很好的练习。
当$ref
为空字符串时,strstr($ref,'@');
return也是空字符串,这就是为什么case strstr($ref,'@'):
匹配开关输入$ref.
问题是,您甚至不能使用
filter_var($ref, FILTER_VALIDATE_EMAIL)
在空输入而不是空字符串的情况下 return false
,但是 switch
进行松散比较,这意味着 "" == false
会 return true
:
http://php.net/manual/en/types.comparisons.php#types.comparisions-loose
因此,我看到的唯一解决方案是使用 ===
运算符的 if 语句:
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";
}
OP 问题:“为什么默认值还包括我为 case strstr($ref,'@') 设置的文本?”
答案:输出后没有break;
,因此通过进入默认情况。
更新: 解决在 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;
}