【问题标题】:PHP switch statement produces wrong results when falsy values are used使用虚假值时 PHP switch 语句会产生错误的结果
【发布时间】:2016-11-11 20:42:50
【问题描述】:

我注意到,当使用具有虚假值的变量时,switch 语句会产生错误的结果。

例如:

$total = 0;     // Same results with '' as a value


switch ($total) {
case 5:
 echo "Five";
break;

case 10:
 echo "Ten";
break;

case $total >= 10:
 echo "More than or equal to one";
break;

default :
 echo "Anything";
}

此脚本回显的字符串是“大于或等于一”。

你能告诉我是否需要做一些不同的事情来使 switch 语句使用假值吗?如果您更喜欢这样的东西,链接也会非常有帮助,任何形式的帮助都会受到欢迎。

感谢您的宝贵时间。

【问题讨论】:

  • case $total >= 10: ?您不能像那样单独使用(大于或等于)表达式,您只能分配;表达式在if 中计算,我看不出你是如何测试它的。
  • @Fred-ii- 感谢您的评论。你确定不能这样吗?我认为这并没有真正被认为是错误的(例如:stackoverflow.com/a/24813225/3915624)。
  • 注意switch 的用法switch (true) { ,而不是switch ($variable)。见eval.in/676379eval.in/676378
  • 哦,我明白了;嗯,这对我来说是第一次。一个人永远不会停止学习;-)
  • @chris85 $total >= 10 返回truefalse。当它与整数 $total 进行比较时,它会被转换为 10。所以它相当于case 1:case 0:,具体取决于$total 的值。

标签: php


【解决方案1】:

switch 中传递的值将与每个案例的值进行比较。在这种情况下:

$total >= 10

首先进行评估,然后与$total 进行比较。 $total >= 10

布尔(假)

通过松散比较(switch 使用)0false 匹配。

var_dump(false == 0);

布尔(真)

所以输出是:

大于或等于一

如果不寻找相等的比较,我会使用if/elseifs、http://php.net/manual/en/control-structures.elseif.php

【讨论】:

  • 好吧,这很尴尬,我不确定我睡眠不足是否可以解释这一点。我明白你的意思,但我仍然想知道 switch 语句是否有解决方法(就像三元运算符的情况一样)。
  • 另外,我注意到 if/else 确实适用于零,但它不适用于其他虚假值,例如空字符串。有那么一刻,我想在 SO 上问另一个问题,以获得 if/else 解决方法,但我想我会停止这种疯狂。
【解决方案2】:

switch 语句在逻辑上等同于一组级联的if-else 语句;将您放在case 上的每个表达式与放在switch 上的表达式进行比较(使用==)。

您的代码与以下相同:

$total = 0;

if ($total == 5) {
    echo "Five";
} elseif ($total == 10) {
    echo "Ten";
} elseif ($total == ($total >= 10)) {
    echo "More than or equal to one";
} else {
    echo "Anything";
}

现在应该很清楚了。前两个if 条件的计算结果为FALSE,但第三个条件的计算结果为TRUE,并打印消息“大于或等于一”。

阅读有关switch statementcomparing values 的PHP 方式的更多信息。

【讨论】:

  • 感谢您的评论,但我关于是否有办法使用带有虚假值(应视为实际值)的 switch 的问题仍然存在。例如,我知道这可以通过三元运算符 if ??用于代替 ?:,我想知道 switch 语句是否有类似的解决方案。
  • 恐怕我没听懂你的问题。 switch 使用 == 将您放入 switch 的表达式与您放入每个 case 的表达式进行比较。它一次进行一次比较,按照case 语句在代码中的顺序,直到一次比较结果为TRUE。如果它们都没有评估为TRUE,那么它会转到default 标签(如果存在)。在您的示例中,$total0$total >= 10 的计算结果为 FALSE。由于根据 PHP 的比较规则,0FALSE 相等(==),因此存在匹配,并采用分支 case $total >= 0:
  • 你在问题​​中说:“出于某种原因,我几乎不可能发现有人在网上提到这种行为。” -- switch 语句的行为在其 PHP 手册页的第一段和第二个注释中进行了解释:php.net/manual/en/control-structures.switch.php
  • 我只是想知道真正需要使用 0 作为真实值而不是虚假值的人如何克服这种行为引起的问题。例如,可能有一个名为 $extra_cost 的变量,其值为 0,应被视为实际值。但是, case $total == 0 将评估为 false 并且将跳过此案例的代码。我现在知道在使用三元运算符时有解决这种情况的方法,我认为 switch 语句也可能有一个“解决方法”。
  • 所以我应该先检查 PHP wiki 而不是几个论坛/a/任何东西,我接受。但是,就在您复制的句子下方,有一个,这是我主要关心的问题:您能告诉我是否需要做一些不同的事情来使 switch 语句使用假值吗?不过,感谢您的详尽解释,它确实让初学者更容易理解它是如何工作的。
猜你喜欢
  • 2023-03-05
  • 2019-02-04
  • 2012-08-10
  • 1970-01-01
  • 2017-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多